I have some activex as well as forms control (drop downs for testing purpose) on my excel 2007 worksheet. I have binded the data using the code below :
Private Sub ComboBox1_Change()
If ComboBox1.Value = 1 Then
ComboBox2.List = Array("a", "b", "c")
ComboBox2.Value = ComboBox2.List(0)
ElseIf ComboBox1.Value = 2 Then
ComboBox2.List = Array("A", "B", "C", "D")
ComboBox2.Value = ComboBox2.List(0)
End If
End Sub
Private Sub Worksheet_Activate()
ComboBox1.List = Array(1, 2)
ComboBox3.List = Array("Delhi", "Kolkata")
ComboBox3.Value = ComboBox3.List(0)
ComboBox4.List = Array("Delhi6", "Kolkata71")
ComboBox4.Value = ComboBox4.List(0)
End Sub
Private Sub UserForm_Initialize()
ComboBox1.List = Array(1, 2)
End Sub
But when I reopen my worksheet, the comboboxes are opening in the state in which they were
closed and no data remains in the dropdown. Please advise as to which event I'm missing to fire??
Thanks in advance...
I found out (taking help from a friend of mine) the mistake that I was making... UserForm_Initialize function I was using in my sheet should not be used at all. Secondly Worksheet_Activate would not be used as well.
The required functon is
Private Sub Workbook_Open()
Sheets("Print_Sheet").ComboBox1.List = Array(1, 2, 3, 4)
Sheets("Print_Sheet").ComboBox3.List = Array("Delhi", "Kolkata")
Sheets("Print_Sheet").ComboBox3.Value = ComboBox3.List(0)
Sheets("Print_Sheet").ComboBox4.List = Array("Delhi6", "Kolkata71")
Sheets("Print_Sheet").ComboBox4.Value = ComboBox4.List(0)
End Sub
This would be used in ThisWorkbook under Microsoft Excel Objects.
Now the combos are populated properly.
Related
I have several arrays named : Array1, Array2, Array3, ... and also some comboboxes named: cboArray1, cboArray2, cboArray3, ....
How can i write a GENERAL code to add elements of each array to corresponding combox. I know following code works, but its not GENERAL and ABSTRACT.
For i = 0 To Array1.Length - 1
cboArray1.Items.Add(Array1(i))
Next
For i = 0 To Array2.Length - 1
cboArray2.Items.Add(Array2(i))
Next
...
Working procedure maybe as follows: 1. Find all comboboxes in form (easy) 2. extract name of a combox (easy) 3. find similar-named array from code (difficult) 4. ....
I can use other sets like List, ... if it makes sense.
Here's what you're asking for using Reflection...though I'm not sure how useful this really is:
Public Class Form1
Private Array1 As String() = {"cat", "dog", "fish"}
Private Array2 As String() = {"alpha", "beta", "gamma"}
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
WireComboBoxes(Me)
End Sub
Private Sub WireComboBoxes(ByVal container As Control)
For Each ctl As Control In container.Controls
If TypeOf ctl Is ComboBox AndAlso ctl.Name.ToUpper.StartsWith("CBO") Then
Dim cb As ComboBox = DirectCast(ctl, ComboBox)
Dim arrName As String = cb.Name.Substring(3)
Dim fi As System.Reflection.FieldInfo = Me.GetType.GetField(arrName, Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Public Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.IgnoreCase)
If Not IsNothing(fi) Then
cb.DataSource = fi.GetValue(Me)
End If
ElseIf ctl.HasChildren Then
WireComboBoxes(ctl)
End If
Next
End Sub
End Class
I'm running into an odd issue. I have 2 Userform, at first Userform2 was inside Userform1, but I wasn't able to make it run. After that I made that a Sub in my Module call Userform2 after other once Userform1 is done.
The problem is the Userform2 is a Multiselect Listbox, and I save each selection in an array and when the Userform2 unloads the array seems to be empty.
I have checked for hours many errors like: I have no explicit option on, but the code is pretty short and I have looked for the array within my code and it only appears on the exact parts I wanted it to be.
Neither the public array as variant was a problem, because it is outside the Userform and in the original Module.
I'm from Chile so some variables have names in Spanish and my English might not be so good, I'll do my best to explain my self.
Here is the code:
Global lenarrv
Global Arrver
Global BoxPMData
Global anno
Global PMDATAarray
Global LenPMDArray
Public varfamilia As Variant
Public pampm As Variant
Sub AbrirMaestro(ByVal anno As Variant)
Application.ScreenUpdating = False
UserForm1.Show
UserForm2.Show
Dim Arrver() As Variant
Dim lenarrv As Long
contentosrcontento = 1
lenarrv = UBound(pampm)
For tt = 0 To lenarrv - 1
ReDim Arrver(contentosrcontento)
Arrver(contentosrcontento) = pampm(tt)
contentosrcontento = contentosrcontento + 1
Next tt
lenarrv = UBound(Arrver)
Inputbox_PMDATA anno
End Sub
Here comes the Userforms:
Private Sub UserForm_Activate()
Me.StartUpPosition = 1
Me.Left = Application.Left + Application.Width - Me.Width - 400
End Sub
Private Sub UserForm_Initialize()
Dim listaitems As Variant
Workbooks("MAESTROS.xlsx").Activate
numerofilas = Workbooks("MAESTROS.xlsx").Sheets("VERTICALES").Cells(2, 1).End(xlDown).Row
listaitems = Workbooks("MAESTROS.xlsx").Sheets("VERTICALES").Range("A2:A" & numerofilas)
listaitems = Application.WorksheetFunction.Transpose(listaitems)
For h = 1 To numerofilas - 1
ListBox1.AddItem listaitems(h)
Next h
Workbooks("MAESTROS.xlsx").Close False
End Sub
Public Sub CommandButton1_Click()
Dim i As Integer
Dim count As Integer
count = 1
For i = 0 To ListBox1.ListCount - 1
If ListBox1.Selected(i) = True Then
ReDim pampm(count)
pampm(i) = ListBox1.List(i)
count = count + 1
End If
Next i
Unload UserForm2
End Sub
Here is UserForm1 :
Private Sub UserForm_Activate()
Me.StartUpPosition = 1
Me.Left = Application.Left + Application.Width - Me.Width - 400
End Sub
Private Sub UserForm_Initialize()
Dim ListItems As Variant
MsgBox ("Elegir el archivo MAESTRO")
Master = Application.GetOpenFilename(MultiSelect:=False)
isBool = VarType(Master) = vbBoolean
If isBool Then If Not Master Then End
Application.ScreenUpdating = False
Set abrirlibro = Workbooks.Open(Master)
numrows = abrirlibro.Worksheets("MASTERFAMILIA").Cells(2, 2).End(xlDown).Row
ListItems = abrirlibro.Worksheets("MASTERFAMILIA").Range("B2:B" & numrows)
ListItems = Application.WorksheetFunction.Transpose(ListItems)
For i = 1 To numrows - 1
ComboBox1.AddItem ListItems(i) ' populate the listbox
Next i
'abrirlibro.Close False
'Set abrirlibro = Nothing
End Sub
Public Sub CommandButton1_Click()
varfamilia = ComboBox1.value
Unload UserForm1
End Sub
I can't past the full code since there are more than 2k lines..
Any help is welcome.
Greetings!
you have to change
Public pampm As Variant
to
Public pampm() As Variant
and
ReDim pampm(count)
to
ReDim Preserve pampm(count)
i have some array and a combobox in excel vba, when from is active program set hozelistname value to combobox1. arrays is like below:
hozelistname=("zahedan","zabol")
hozezahedan=(1,2,3,4)
hozezaol=(5,6,7)
now when combobox1 change, i want it show the list of selected array. for example when i select zahedan from list i want it alert the value of zahedan array named hozezahedan and also for zabol.
i wrote the below code but not working! any body to help me?
Private Sub ComboBox1_Change()
dim arrayname,str as string
dim i as integer
arrayname = "hoze" & ComboBox1.text
for i= lbound(arrayname) to ubound(arrayname)
msgbox(arryname(i))
next
End Sub
Option Explicit
Private dicArrays As Scripting.Dictionary
Sub SetUP()
Dim arrTestOne(5) As String
Dim arrTestTwo(10) As String
Set dicArrays = New Scripting.Dictionary
dicArrays.Add "TestOne", arrTestOne
dicArrays.Add "TestTwo", arrTestTwo
End Sub
Sub Reference_Example()
Dim a() As String
a = dicArrays("TestTwo")
End Sub
I hope this explains a little better.
Its unclear what you are after but does the below help you through it?
'This block of code goes right at the top of the form
Option Explicit
Dim hozelistname(1) As String
Dim hozezahedan(3) As String
Dim hozezabol(2) As String
Private Sub ComboBox1_Change()
Dim i As Integer
Dim AryLocal() As String
'set the local array based on the combobox
Select Case Me.ComboBox1
Case "zahedan"
AryLocal = hozezahedan
Case "zabol"
AryLocal = hozezabol
Case Else
ReDim AryLocal(0)
End Select
'show the local array
For i = 0 To UBound(AryLocal, 1)
MsgBox (AryLocal(i))
Next
End Sub
Private Sub UserForm_Activate()
Dim LngCounter As Long
'Set up the lists
hozelistname(0) = "zahedan"
hozelistname(1) = "zabol"
'Set up each result
hozezahedan(0) = "1"
hozezahedan(1) = "2"
hozezahedan(2) = "3"
hozezahedan(3) = "4"
hozezabol(0) = "5"
hozezabol(1) = "6"
hozezabol(2) = "7"
'set the combobox
For LngCounter = 0 To UBound(hozelistname, 1)
Me.ComboBox1.AddItem hozelistname(LngCounter)
Next
End Sub
The next steps would be populating the ComboBox and arrays based on list written in Excel and not hardcoded ones.
I'm making some sort of football database where I would input data using a userform and where I want to retrieve data from my excel database.
I have a worksheet named: "wedstrijden" This worksheet contain the columns: Date, HomeTeam, AwayTeam, HomeScore,AwayScore, HomeOdds and AwayOdds
My other worksheet is named: "ingevenuitslagen" This worksheet contains my userform called UitslagenIngeven
Using the code below I'm able to input my data from the userform to my "wedstrijden" worksheet
Private Sub putAway_Click()
Dim ingevenuitslagen As Worksheet
Set ingevenuitslagen = ThisWorkbook.Sheets("wedstrijden")
NextRow = ingevenuitslagen.Cells(Rows.Count, 1).End(xlUp).Row + 1
ingevenuitslagen.Cells(NextRow, 1) = CDate(date_txt.Text)
ingevenuitslagen.Cells(NextRow, 2) = UitslagenIngeven.cboHomeTeam
ingevenuitslagen.Cells(NextRow, 3) = UitslagenIngeven.cboAwayTeam
ingevenuitslagen.Cells(NextRow, 4) = UitslagenIngeven.cboHScore
ingevenuitslagen.Cells(NextRow, 5) = UitslagenIngeven.cboAScore
ingevenuitslagen.Cells(NextRow, 6) = Val(UitslagenIngeven.hodds_txt.Text)
ingevenuitslagen.Cells(NextRow, 7) = Val(UitslagenIngeven.aodds_txt.Text)
End Sub
But this is only to put away 1 row. I would like to make the possibility to put away 10 or 15 rows at once. So I would make a userform with the possibility to put away 20 rows BUT it should be able to put away only those rows that are filled in.
Is this possible? And how should I adjust my userform? Can I just copy the text and combobox areas ?
How to work with a Data Array
You'll need to create a new button, you'll have :
one for adding the data set to the data array (here CommandButton1) and
one to add the data array to the data base (here CommandButton2).
I also prefer to work with a Named Range for the Data Base, here it is called Db_Val but you can rename this to fit your needs! ;)
Code to place in the UserForm to fill the data array :
Public ingevenuitslagen As Worksheet
Public DataA() '----These lines should be at the top of the module
'----Code to Set the dimension of the Data array
Private Sub UserForm_Initialize()
Dim DataA(7, 0)
Set ingevenuitslagen = ThisWorkbook.Sheets("wedstrijden")
'----Rest of your code
End Sub
'----Code to add a data set to the data array
Private Sub CommandButton1_Click()
UnFilter_DB '----See below procedure
DataA(1) = CDate(date_txt.Text)
DataA(2) = UitslagenIngeven.cboHomeTeam
DataA(3) = UitslagenIngeven.cboAwayTeam
DataA(4) = UitslagenIngeven.cboHScore
DataA(5) = UitslagenIngeven.cboAScore
DataA(6) = Val(UitslagenIngeven.hodds_txt.Text)
DataA(7) = Val(UitslagenIngeven.aodds_txt.Text)
ReDim Preserve DataA(LBound(DataA, 1) To UBound(DataA, 1), LBound(DataA, 2) To UBound(DataA, 2) + 1)
End Sub
'----Code to sent the data array to the DB
Private Sub CommandButton2_Click()
ReDim Preserve DataA(LBound(DataA, 1) To UBound(DataA, 1), LBound(DataA, 2) To UBound(DataA, 2) - 1)
SetData DataA
End Sub
Procedure to print in the database the data array that you pass from the user form :
Here the data base is the Named Range Db_Val in ingevenuitslagen sheet
Public Sub SetData(ByVal Data_Array As Variant)
Dim DestRg As Range, _
A()
'----Find the last row of your DataBase
Set DestRg = ingevenuitslagen.Range("Db_Val").Cells(ingevenuitslagen.Range("Db_Val").Rows.Count, 1)
'----Print your array starting on the next row
DestRg.Offset(1, 0).Resize(UBound(Data_Array, 1), UBound(Data_Array, 2)).Value = Data_Array
End Sub
Sub to unfilter the DB you are working with :
Public Sub UnFilter_DB()
'----Use before "print" array in sheet to unfilter DB to avoid problems (always writing on the same row if it is still filtered)
Dim ActiveS As String, CurrScreenUpdate As Boolean
CurrScreenUpdate = Application.ScreenUpdating
Application.ScreenUpdating = False
ActiveS = ActiveSheet.Name
ingevenuitslagen.Activate
ingevenuitslagen.Range("A1").Activate
ingevenuitslagen.ShowAllData
DoEvents
Sheets(ActiveS).Activate
Application.ScreenUpdating = CurrScreenUpdate
End Sub
Good day all.
I have this same challenge. Mine is to be able to place a Customer's Orders. With the code I have I can only place one product per order at a time for the customer. I want to be able to place multiple products per order for one customer at the same time in a Userform and it will update multiple rows. The code below can only update one row with one product in a row for one customer:
Private Sub cmdAdd_Click()
Dim lRow As Long
Dim ws As Worksheet
lRow = ws.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
With ws
.Cells(lRow, 1).Value = Me.Data1.Value
.Cells(lRow, 2).Value = Me.Data2.Value
.Cells(lRow, 3).Value = Me.Data3.Value
.Cells(lRow, 4).Value = Me.Data4.Value
.Cells(lRow, 5).Value = Me.Data5.Value
.Cells(lRow, 6).Value = Me.Data6.Value
.Cells(lRow, 7).Value = Me.Data7.Value
.Cells(lRow, 8).Value = Me.Data8.Value
.Cells(lRow, 9).Value = Me.Data9.Value
.Cells(lRow, 10).Value = Me.Data10.Value
End With
End Sub
The above can only update One product per customer. A customer could place order for more than one product.
Say I have two files Form1.frm and Module1.bas in a Visual Basic 6 project.
Form1.frm:
Public myArray As Variant
Private Sub Form_Load()
ReDim myArray(2)
Call PopulateArrays
End Sub
Module1.bas:
Public Sub PopulateArrays()
Form1.myArray(0) = Array(1, 2, 3)
Form1.myArray(1) = Array(4, 5, 6)
Form1.myArray(2) = Array(7, 8, 9)
End Sub
The issues is that once the code runs, 'myArray' remains empty.
If I put the PopulateArrays Sub within the main Form1.frm the arrays do populate.
Any thoughts?
There are certain things you can't declare in an object module (userforms are just special object modules) and one of them is arrays. If you had declared
Public myArray() As Variant
Then you would have got a compile error that said as much and would have known. But since you declared as Variant, the compiler didn't complain, but the assignment just doesn't work.
One option is to make the Variant array private and use property statements (this is VBA, but should be the same for VB6). In the userform
Private mmyArray() As Variant
Public Property Get myArray() As Variant
myArray = mmyArray
End Property
Public Property Let myArray(lmyArray As Variant)
mmyArray = lmyArray
End Property
Private Sub UserForm_Click()
MsgBox Join(Me.myArray(0), "_")
End Sub
Private Sub UserForm_Initialize()
ReDim mmyArray(2)
PopulateArrays
End Sub
And in a standard module
Public Sub PopulateArrays()
Dim ar(0 To 2) As Variant
ar(0) = Array(1, 2, 3)
UserForm1.myArray = ar
End Sub
I see you've used a workaround to let your Form1 hold a public array. However, I think a better solution would be: (A) move the array to the module and make it public (B) create accessor/mutator functions for it.
If you aren't keeping multiple instances of the form at the same time, then (A) is the simplest solution.
Here is the code I tested for (A),
Form:
Private Sub UserForm_Initialize()
Call PopulateArrays
Call displayArray
End Sub
Private Sub displayArray()
Dim v1 As Variant
Dim s As String
For Each v1 In myArray
s = s + Join(v1, ", ") + vbNewLine
Next v1
MsgBox s
End Sub
Module:
Dim form1 As UserForm1
Public myArray As Variant
Public Sub start()
Set form1 = New UserForm1
End Sub
Public Sub PopulateArrays()
ReDim myArray(2)
myArray(0) = Array(1, 2, 3)
myArray(1) = Array(4, 5, 6)
myArray(2) = Array(7, 8, 9)
End Sub