adressing object by variable - vba

In my form I have a number of 8 text fields named with consecutive numbers (tbx_MyID1 to tbx_MyID8). I want to loop through all 8 text fields to create new records out of the text fields' values. So I am trying to store the text fields names in a variable and address the text fields by this variable. This only creates an error, saying the object does not exist.
Private Sub btn_Enter_Click()
Dim db As Database
Dim rs As Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("tbl")
Dim x As Integer
x = 1
While x < 9
Dim y As String
y = "tbx_MyID" & x
rs.AddNew
rs.Fields("ID") = Me!y.Value
x = x+1
Wend
rs.Update
rs.Close
Set rs = Nothing
db.Close
End Sub

Replace rs.Fields("ID") = Me!y.Value
with rs.Fields("ID") = Me.Controls("tbx_MyID" & x)
It will work because the default property of the underlying control type (a text box) is the "Text" property.
There are a lot of ways to reference controls dynamically on a form. It might be clearer to declare a variable for the text box, get a reference to it, and then specifically reference the Text property:
Dim ctl As TextBox
Dim x As Integer
x = 1
While x < 9
ctl = Me.Controls("tbx_MyID" & x)
rs.AddNew
rs.Fields("ID") = ctl.Text
x = x+1
Wend

As noted previously, you need to access the form's Controls property.
Additionally, you probably want to store your text box prefix and the number of text boxes in constants, to make your code more readable.
Finally, even Microsoft suggests you replace While...Wend loops with the Do...Loop construct. So updated code might look something like this:
Option Explicit
Private Const TEXT_BOX_PREFIX As String = "tbx_MyID"
Private Const TEXT_BOX_COUNT As Integer = 8
Private Sub Command18_Click()
Dim x As Integer
Dim txtBox As Access.TextBox
For x = 1 To TEXT_BOX_COUNT
Set txtBox = Me.Controls(TEXT_BOX_PREFIX & x)
Debug.Print txtBox.Value
' put your code to add/update records here.
Next x
End Sub
If you clarify your question to indicate how specifically the text boxes relate to new records, I can update my answer to address that part.

Related

If possible: How to write a Word Macro which swap the content of the two textboxes on an active page?

I have a Word Document which creates indexcards for books via series. On every page information about a single book. Sometimes two fields have to be swaped for a specific item. So for my collegue it would save a lot of work if that would be possible with a single click. I have programming experience but not so much Office and no VBA.
Is it possible to do something like below? :
Pseudo code:
dim temp as string
dim temp2 as string
select first textbox on active page
temp = select.Text
select second textbox on active page
temp2 = select.Text
select.Text = temp
select first textbox on active page
select.Text = temp2
Any ideas what functions to look in would be welcome. Especialy if it is possible to select the first and second textbox of a single (active) page.
There is probably a better way to do this, but textboxes in word I find to be a real pain.
Here we set the names of the boxes, how you determine the order I'm unsure, maybe a check using titles, or the anchor point. The ID property is not the index so we can't use that.
Sub Rename()
Dim textbox As Object
Dim iter As Long
iter = 1
For Each textbox In ActiveDocument.Shapes 'I'm not sure how to set names manually
textbox.Name = "TextBox " & iter
iter = iter + 1
Next
End Sub
Assuming you have the boxes named in the order they appear:
Sub TextSwap()
Dim targetbox As Long
Dim val1 As String
Dim val2 As String
targetbox = InputBox("Enter an Integer relating to the position of the textbox")
val1 = ActiveDocument.Shapes("TextBox " & targetbox).TextFrame.TextRange.Text
val2 = ActiveDocument.Shapes("TextBox " & (targetbox + 1)).TextFrame.TextRange.Text
ActiveDocument.Shapes("TextBox " & targetbox).TextFrame.TextRange.Text = val2
ActiveDocument.Shapes("TextBox " & (targetbox + 1)).TextFrame.TextRange.Text = val1
End Sub
You'll need to check the input to make sure you don't get errors. I'm also not convinced the names of the textboxes are reliable, but this should work as long as you aren't doing anything too crazy.

How to reference similar named textboxes within a loop, with the loop iteration [duplicate]

So I have a table that has a list of totals im trying to display on a form, I have 10 totals I need to get from the totals table and display in 10 textboxes on the form.
The 10 textboxes are "A1, A2, A3..." and its using DLookup to find the ID field number.
It seems like its a syntax issue with Me.TEXTX & X1.Value though I'm not sure how else I can type it.
Hope this makes sense. Thanks!
Private Sub UPDATETOTALS()
Dim FORMX As String
FORMX = "GRID"
Dim TEXTX As String
TEXTX = "A"
Dim TABLENAMEx As String, FINDFIELDx As String, GETFIELDx As String
TABLENAMEx = "GRID_TOTALS"
FINDFIELDx = "[ID]="
GETFIELDx = "TODAY"
Dim X1 As Integer
For X1 = 1 To 10
Me.TEXTX & X1.Value = DLookup(GETFIELDx, TABLENAMEx, FINDFIELDx & X1)
Next X1
End Sub
You cannot access an object reference directly using a concatenated string, as such reference is not of string data type.
Instead, you will need to access the object from the relevant collection (in this case, the Controls collection), by supplying the name of the object (as a string) to the Item method of that collection.
Since the Item method is the default method for a collection, the item name can immediately follow the collection as an argument.
For example:
For X1 = 1 To 10
Me.Controls(TEXTX & X1).Value = DLookup(GETFIELDx, TABLENAMEx, FINDFIELDx & X1)
Next X1

VBA convert textbox entry to an integer

I am trying to convert a textbox entry to an integer:
Dim cplayers() As Variant: cplayers = Array ("Danny", "Freddy", "Billy", "Tommy")
Dim i As Integer
i = CInt(TextBox3)
MsgBox (cplayers(i) & " is on first base.")
When I run it now, the message box always reads "Danny is on first base." so it must be reading the textbox as empty and assuming the entry is 0 then. What should I change?
You can use an ActiveX Text Box to import the value.
To Insert: Developer Tab > Insert > ActiveX Controls > Text Box (ActiveX Control)
You can then extract your value as such:
Option Explicit
Sub Test()
Dim cplayers() As Variant: cplayers = Array("Danny", "Freddy", "Billy", "Tommy")
Dim i As Integer
i = TextBox1.Value
MsgBox cplayers(i) & " is on first base."
End Sub
You could also refer to the object but that would be overkill here.
The field that holds the actual entry for the Textbox seems to be "TextBox3.text"
Dim cplayers() As Variant: cplayers = Array ("Danny", "Freddy", "Billy", "Tommy")
Dim i As Integer
i = CInt(TextBox3.text)
MsgBox (cplayers(i) & " is on first base.")
There is also a check that can help you to prevent wrong inputs in the calculations. You can use isNumeric() to determine if the entered value is a valid number like If IsNumeric(TextBox3.text) Then

VB.NET - How do I use a variable in another variables name?

How would I do something similar to this:
Dim amnt As Integer
For x As Integer = 1 To 6
If amnt[x] = 0 Then
btn[x].Enabled = False
End If
Next x
What I mean is, can I reference a variable by using another variable in the name. For example, if "x" were to be 4, then I want to change the button "btn4" to .Enabled = False, but I also want to be able to change the button that I'm changing properties of. So like
If (variablesName & x) = 0 Then
If x is 4 then it should look like this
If variablesName4 = 0 Then
If you mean evaluating a variable by supplying it's name as a string - then this cannot be done in VBA.
For example:
Dim testVar As Integer
Dim v As String
v = "Var"
testVar = 5
Debug.Print test & v '// error
Debug.Print "test" & v '// prints "testVar" as a string
Debug.Print "testVar" '// prints "testVar" as a string
Debug.Print testVar '// prints "5" <~~ only way it can be done
However, for some controls, and some other items - you can access the parent collection and supply a string value to get the correct index. So something like:
For i = 1 To 10
'// Will set checkboxes 1 to 10 to be checked
myForm.Controls("Checkbox" & i).Checked = True
Next
As it stands - it's too broad a question to give a definitive answer, but depending on the kind of objects you are working with you may be able to access a parent collection in this way.

Set parent Control to another control

I need to set a parent Control to another control using the VBA code.
Actually i am looping to create differents controls dynamically and i want now to link them by child-parent.
Do someone has an idea ?
Here is the function where i create a new control and i set some values. And the last assignment is where i want to set the parent
Public Function apply_change(ihm_f, oNode, iMyName$, project$)
Dim new_elem
Dim oSubNodes As IXMLDOMNode
If oNode.Attributes.getNamedItem("Type").Text <> "Page" Then
If (oNode.Attributes.getNamedItem("Type").Text = "RefEdit") Then
Set new_elem = ihm_f.Designer.Controls.Add("RefEdit.Ctrl", oNode.nodeName, True)
Else
Set new_elem = ihm_f.Designer.Controls.Add("Forms." & oNode.Attributes.getNamedItem("Type").Text & ".1", oNode.nodeName, True)
End If
With new_elem
On Error Resume Next
.Width = oNode.Attributes.getNamedItem("Width").Text
.Top = oNode.Attributes.getNamedItem("Top").Text
.Left = oNode.Attributes.getNamedItem("Left").Text
.Height = oNode.Attributes.getNamedItem("Height").Text
Set .Parent = get_parent(oNode.ParentNode.nodeName, oNode, ihm_f)
End With
If oNode.Attributes.getNamedItem("Type").Text = "MultiPage" Then
Call new_elem.Pages.Remove(0)
Call new_elem.Pages.Remove(0)
For Each oSubNodes In oNode.ChildNodes()
Call new_elem.Pages.Add(oSubNodes.BaseName, oSubNodes.Attributes.getNamedItem("Caption").Text, oSubNodes.Attributes.getNamedItem("Index").Text)
Next oSubNodes
End If
End If
Set apply_change = ihm_f
End Function
The getparent function return a Controle which can be anything .. like textbox or combo box etc..
You provide so little information in your question that it is difficult to guess your objective.
However, I am guessing that you want to record that Control Xxxxx is the parent of control Yyyyy where the definition of “parent” has nothing to do with Excel’s definition of parent. I am further guessing you do not know how to access controls by number.
The macro below lists the name, type and top position of every control on a form by its index number within the collection Controls. Any property of a control is accessible in this way. If control Xxxxx is the parent of control Yyyyy, you can scan the collection to find their index numbers when the form loads and record this information for use when required.
Private Sub UserForm_Initialize()
Dim InxCtrl As Long
Dim LenNameMax As Long
Dim LenTypeMax As Long
LenNameMax = 0
For InxCtrl = 0 To Controls.Count - 1
If LenNameMax < Len(Controls(InxCtrl).Name) Then
LenNameMax = Len(Controls(InxCtrl).Name)
End If
If LenTypeMax < Len(TypeName(Controls(InxCtrl))) Then
LenTypeMax = Len(TypeName(Controls(InxCtrl)))
End If
Next
Debug.Print PadR("Name", LenNameMax) & "|" & PadR("Type", LenTypeMax) & "| Top"
For InxCtrl = 0 To Controls.Count - 1
Debug.Print PadR(Controls(InxCtrl).Name, LenNameMax) & "|" & _
PadR(TypeName(Controls(InxCtrl)), LenTypeMax) & "|" & _
PadL(Format(Controls(InxCtrl).Top, "#,###.00"), 8)
Next
End Sub