PDA

View Full Version : Passing arrays between userform parts



LemonBradder
10-20-2014, 09:25 AM
Hi,

The following code are two parts of the code for a userfrom. The Sub FillVars is usings variables from a Call in the Modules code.


Sub FillVars(LabelStr As String, StringsArr() As String, bookMarks() As String)
Dim numOptions As Integer, i As Integer
Dim OptionsArr() As String
Dim selectionInt As Integer
numOptions = UBound(StringsArr, 1)
ReDim OptionsArr(numOptions)
For i = 0 To numOptions
OptionsArr(i) = StringsArr(i, 0)
Next i
Label1.Caption = LabelStr
ComboBox1.List = OptionsArr
End Sub

Private Sub OkButton_Click()
selectionInt = ComboBox1.ListIndex
If selectionInt >= 0 Then
ActiveDocument.bookMarks(bookMarks(0)).Range.Text = StringsArr(selectionInt, 1)
ActiveDocument.bookMarks(bookMarks(1)).Range.Text = StringsArr(selectionInt, 2)
End If
selectionInt = -1
Unload ExportForm
End Sub


My issue is that OkButton_Click (triggered from the pressing of a command button) does not have access to StringsArr() or bookMarks() in order to do it's bookMarks commands. Is there any why to pass these arrays to OkButton_Click in the same way that ComboBox1.List is available.

I do not want to make a second combobox that just passes arrays. People will only ask why it is there.

I am aware that all functions can work with Public Arrays but I want to avoid doing this for the following reasons:
1. I have been told that it is risky using global functions when making tools to be used by many users (such as this current Project) (i.e. Global i As Integer will clash a lot of beginners codes)
2. The Calling of the user form is done multiple times. This means constantly resetting and error checking the arrays between calls as I don't want to risk an instance using the arrays from a previous instance (which will work as they require the same format).
3. The StringsArr instances will all be ,3 times x, 2D arrays where x varies between intances. In order to support a Public array I would have to write ReDim and Ubound loops to handle lot's of x variation to move from specific instance array to Public array. I could but it seems inefficient to have code copying arrays one for one rather than find a By Reference method.

Please let me know how you would handle this case? Thanks in advance.
James.

ranman256
10-20-2014, 09:28 AM
You must declare StringsArr in the top of the FORM module. (FORM)
In order for it to be a module level variable.

PRIVATE StringsArr

gmaxey
10-21-2014, 06:55 AM
Why don't you just use the combobox?


ActiveDocument.bookMarks(bookMarks(0)).Range.Text = ComboBox1.Column(0)
ActiveDocument.bookMarks(bookMarks(1)).Range.Text = ComboBox1.Column(1)

LemonBradder
10-22-2014, 07:31 AM
Thanks ranman256

Private infoArr() As String
Private bookMarks() As String

Now work through out the form which is great.
I can’t however populate infoArr()/StringsArr() using the FillVars(xx, StringsArr(),xx) input. To fix this I added:

Call inputOneForOne2DArrays(StringsArr, infoArr)

To the FillVars(code) and it calls this:

Function inputOneForOne2DArrays(orignalArr() As String, targetArr() As String)
Dim xCo, yCo, xSize, ySize As Integer
xSize = UBound(orignalArr, 1)
ySize = UBound(orignalArr, 2)
ReDim targetArr(xSize, ySize)
For xCo = 0 To xSize
For yCo = 0 To ySize
targetArr(xCo, yCo) = orignalArr(xCo, yCo)
Next yCo
Next xCo
End Function

It would be nice to know a method of passing an array from a module to a form to use privately using only the module call. (I guess the point of private variables is that they can’t be picked up by any piece of code.)

gmaxey
It is because the ComboBox did not contain the information that was populating the bookmarks. Each option contained three parts, one for the selection list and two for populating the bookmarks. The combobox would display StringsArr(i, 0), and selecting ‘i’ would populate the bookmarks with StringsArr(i, 1) and StringsArr(i, 2).
This means that the combobox could be used for passing bookMarks() but not StringsArr()/infoArr(), which are both needed.


Thanks for the help guys. :content:

snb
10-23-2014, 06:59 AM
I do not want to make a second combobox that just passes arrays. People will only ask why it is there.

They won't ask if they can't see it: Listbox100.visible=false; Combobox100.visible=false

SamT
10-24-2014, 10:12 AM
Other options include

Inside the Form module, Use Ctrl+H to change the variable names to frm_ & [Original Var Name.] Then add Public Functions to return those Var.Values to any outside caller, or use User Defined Properties. See "Get" or "Let" in help

Examples:

Form Code

Private frm_infoArr() As String
Private f_bookMarks() As String 'Different prefix, same intent


Public Function infoArr() As Variant
'One function cannot retrieve and edit a variable
InfoArr = frm_InfoArr
End Function

Property Get BookMarks()
'Two Property statements can have the same name.
'Property Get [OneName] retrieves the Variable's value and
'Property Let [OneName] changes the Value.

BookMarks = f_bookMarks
End Property

Outside Form Code

Sub WhatEver()
Dim MyVar as Variant
Dim OtherVar As Variant

MyVar = UserForm1.BookMarks 'Uses Form Custom Property
'If the Form has a Property Let, then
'UserForm1.BookMarks = MyVar is possible

OtherVar = UserForm1.infoArr 'Uses Form Public Function
End Sub