Click and recognize part of text in textbox vb.net - string

I am trying to make a program that utilises a textbox that has text options listed in it that can be clicked on.
As a textbox example:
[Selection:<1><2><3>]
so the user could then as example click on (over the text) <2> to select the 2nd option or <3> so select the 3rd option. The idea comes from the AutoCAD commands prompt which uses a similar system.
How would I achieve something like this in vb.net code (if its even possible)?

Try this:
Private Sub TextBox1_Click(sender As Object, e As EventArgs) Handles TextBox1.Click
Dim SplitText As String() = TextBox1.Text.Split(CChar("<"), ">")
Dim SelectedText As String = GetSelectedText()
Dim Options As New List(Of String)
If Not SelectedText = "" Then
For i = 0 To SplitText.Length - 1
If IsNumeric(SplitText(i)) Then
Options.Add("<" & SplitText(i) & ">")
End If
Next
For i = 0 To Options.Count - 1
If SelectedText = Options(i) Then
'Put your code here if it is the current option in the loop equals the selected option.
'I added a messagebox just so you can see the current option.
MessageBox.Show("You selected option: " & Options(i))
End If
Next
End If
End Sub
Private Function GetSelectedText()
Dim CursorPosition As Integer = TextBox1.SelectionStart
Dim SelectedNumber As String = ""
Dim NumberLength As Integer = 0
If CursorPosition = 0 Or CursorPosition = TextBox1.Text.Length Then
Return ""
End If
Do Until Mid(TextBox1.Text, CursorPosition - NumberLength, 1) = "<"
NumberLength += 1
Loop
SelectedNumber = Mid(TextBox1.Text, CursorPosition - NumberLength, NumberLength + 1)
NumberLength = 0
CursorPosition += 1
Do Until Mid(TextBox1.Text, CursorPosition + NumberLength, 1) = ">"
NumberLength += 1
Loop
SelectedNumber &= Mid(TextBox1.Text, CursorPosition, NumberLength + 1)
If IsNumeric(SelectedNumber.Remove(0, 1).Remove(SelectedNumber.Length - 2, 1)) Then
Return SelectedNumber
Else
Return ""
End If
End Function
I put this inside of the textbox click event, and it works. I did not try putting the code in any other events. I assume that the textbox is named: TextBox1.

Here's a quick example showing how to build a "menu" with a LinkLabel:
Public Class Form1
Private menuItems() As String = {"cat", "dog", "fish"}
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim menu As String = "Selection: " & String.Join(", ", menuItems)
LinkLabel1.Text = menu
LinkLabel1.Links.Clear()
For Each item In menuItems
LinkLabel1.Links.Add(menu.IndexOf(item), item.Length)
Next
End Sub
Private Sub LinkLabel1_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles LinkLabel1.LinkClicked
Dim i As Integer = LinkLabel1.Links.IndexOf(e.Link)
Label1.Text = menuItems(i)
End Sub
End Class
Output:

Related

VBA Excel ListView Checkboxes do not show in Userform

I have a UserForm with a MultipageControl (name Controller_MultiPage).
At runtime my code adds pages to the Multipage and creates a newListView on each page.
Every ListView has:
With newListView
.MultiSelect = False
.Width = Controller_MultiPage.Width - 10
.Height = Controller_MultiPage.Height - 20
.View = lvwReport
.HideColumnHeaders = False
.ColumnHeaders.Add Text:="Signal Name", Width:=.Width / 10 * 4
.ColumnHeaders.Add Text:="Type", Width:=.Width / 10
.ColumnHeaders.Add Text:="I/O", Width:=.Width / 10
.ColumnHeaders.Add Text:="Description", Width:=.Width / 10 * 4
.CheckBoxes = True
.FullRowSelect = True
End With
then I populate the newListView with data from an XML file:
For Each node In list
With node.Attributes
Set listItem = newListView.ListItems.Add(Text:=.getNamedItem("Name").Text)
listItem.ListSubItems.Add = .getNamedItem("Type").Text
listItem.ListSubItems.Add = IIf(.getNamedItem("Input").Text = "1", "IN", "OUT")
listItem.ListSubItems.Add = .getNamedItem("Description").Text
listItem.Checked = False
End With
Next
but the checkboxes do not show. I can see the space for them in front of the first column and by clicking that space the checkbox of that particular row then appears. What I also noticed is that if I change the property
listItem.Checked = True
the behavior described above does not change, and when I click the free space in front of the first column (checkboxes space) the chsckbox that then shows up is still unchecked.
Any idea?
The problem seems to be in the behavior of the MultiPage control.
What I noticed was that if I forced the checkboxes' status (checked or unchecked) from the code, using the MultiPage_Change event, then the checkboxes show up.
So what I did was to create a class that holds the status of all checkboxes of all listviews on a single page, instantiate the Class for each ListView and store everything into a Dictionary, using the newListView.Name as Key
Then when the user changes page, the MultiPage_Change event that fires resets all the values of the checkboxes according to the Dictionary stored values.
In the Listview_N_ItemChecked event some other code updates the status of the item stored in the Dictionary.
Kind of cumbersome but it works.
the class (updated):
' Class Name = ComponentsSignalsRecord
Option Explicit
Dim Name As String
' NOTE: Signals(0) will always be empty and status(0) will always be False
Dim Signals() As String
Dim Status() As Boolean
Dim Component As String
Property Let SetComponentName(argName As String)
Component = argName
End Property
Property Get GetComponentName() As String
GetComponentName = Component
End Property
Property Get getSignalName(argIndex) As String
If argIndex >= LBound(Signals) And argIndex <= UBound(Signals) Then
getSignalName = Signals(argIndex)
Else
getSignalName = vbNullString
End If
End Property
Property Get dumpAll() As String()
dumpAll = Signals
End Property
Property Get Count() As Long
Count = UBound(Signals)
End Property
Property Get getStatus(argName As String) As Integer
' returns: -1 = Not Found; 1 = True; 0 = False
getStatus = -1
Dim i As Integer
For i = 0 To UBound(Signals)
If argName = Signals(i) Then getStatus = IIf(Status(i) = True, 1, 0): Exit For
Next
End Property
Property Let setName(argName As String)
Name = argName
End Property
Property Get getName() As String
getName = Name
End Property
Public Sub UncheckAll()
Dim i As Integer
For i = 0 To UBound(Status)
Status(i) = False
Next
End Sub
Public Sub CheckAll()
Dim i As Integer
For i = 0 To UBound(Status)
Status(i) = True
Next
End Sub
Public Sub deleteSignal(argName As String)
Dim spoolSignals() As String
Dim spoolStatus() As Boolean
Dim i As Integer
spoolSignals = Signals
spoolStatus = Status
ReDim Signals(0)
ReDim Status(0)
For i = 1 To UBound(spoolSignals)
If argName <> spoolSignals(i) Then
ReDim Preserve Signals(UBound(Signals) + 1): Signals(UBound(Signals)) = spoolSignals(i)
ReDim Preserve Status(UBound(Status) + 1): Status(UBound(Status)) = spoolStatus(i)
End If
Next
End Sub
Public Sub addSignal(argName As String, argValue As Boolean)
Dim i As Integer
For i = 0 To UBound(Signals)
If argName = Signals(i) Then GoTo bye
Next
ReDim Preserve Signals(UBound(Signals) + 1)
ReDim Preserve Status(UBound(Status) + 1)
Signals(UBound(Signals)) = argName
Status(UBound(Status)) = argValue
bye:
End Sub
Public Sub setStatus(argName As String, argValue As Boolean)
Dim i As Integer
For i = 0 To UBound(Signals)
If argName = Signals(i) Then Status(i) = argValue: Exit For
Next
End Sub
Private Sub Class_Initialize()
ReDim Signals(0)
ReDim Status(0)
End Sub
The Form relevant code. Module level:
Dim myDict As New Dictionary ' the Dictionary
Dim ComponentsSignalsList As ComponentsSignalsRecord ' the Class
for each ListView created, may be one or more for every single MultiPage page :
Set ComponentsSignalsList = New ComponentsSignalsRecord
ComponentsSignalsList.setName = newListView.name
while populating the listview(s) in a loop for each single item added:
ComponentsSignalsList.addSignal List_Item.Text, List_Item.Checked
end of each loop, add the Class instance to the Dictionary:
myDict.Add ComponentsSignalsList.getName, ComponentsSignalsList
Now when changing Page in the MultiPage widget:
Private Sub Controller_MultiPage_Change()
If isLoading Then Exit Sub 'avoid errors and undue behavior while initializing the MultiPage widget
Dim locControl As Control
Dim controlType As String: controlType = "ListView"
With Controller_MultiPage
For Each locControl In .Pages(.value).Controls
If InStr(1, TypeName(locControl), controlType) > 0 Then
Call Check_CheckBoxes(locControl)
End If
Next
End With
End Sub
Private Sub Check_CheckBoxes(argListView As listView)
If argListView.CheckBoxes = False Then Exit Sub 'some ListViews don't have checkboxes
Dim myItem As ListItem
For Each myItem In argListView.ListItems
With myItem
.Checked = myDict.Item(argListView.name).getStatus(.Text)
End With
Next
End Sub
when ticking/unticking a checkbox (note the the ItemChecked event handler is defined in another Class Public WithEvents, where the handler calls this method passing both the ListView ID and the Item object) :
Public Sub ListViewsEvents_ItemCheck(argListView As listView, argItem As MSComctlLib.ListItem)
With argItem
myDict.Item((argListView .name).setStatus argName:=.Text, argValue:=.Checked
End With
End Sub
I just found the answer to the same problem that I also had and I feel so stupid. I had the first column of the Listview set to Width = 0... and thus the checkboxes would no longer show.
I gave it a width and everithing is back to normal...

drag and duplicate a button in a form

I have a form. Inside a form there is a button1.
I want to drag the button1 anywhere inside the form and duplicate it when it drops, but the codes in the button1 is still there.
Language doesn't matter may be C# or VB.NET
Here is how to implement you last thing to your project :
First :
Add another timer to your form design called(Timer2), this time is to handle the movement of the created buttons where the first timer (Timer1) was to handle the movement of the main first button (the once we are duplicating from).
Now this is how your whole code should look like, I explained as much as i can in the code, and if you didn't understand a thing, please ask... :
Public Class Form1
Dim XLoc, YLoc, CreateButtonX As Integer
Dim CreatedButtons As String()
Dim DragedButtonName As String
Dim ButtonsCount As Integer = 1
Dim NewBUT As Button
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If My.Settings.CreatedButtons <> "" Then
'Split the string (CreatedButtons) in the Settings with the char "|" as a separator and loop through all the pats when each part is a different location for a duplicated button.
CreatedButtons = My.Settings.CreatedButtons.Split("|")
Dim Separator As String = "|"
For Each Separator In CreatedButtons
CreateNewButton()
Try
Dim Pos1 As Integer = CreatedButtons(CreateButtonX).IndexOf(":")
Dim Pos2 As Integer = CreatedButtons(CreateButtonX).IndexOf(",")
XLoc = CreatedButtons(CreateButtonX).Substring(Pos1 + 1, Pos2 - Pos1)
YLoc = CreatedButtons(CreateButtonX).Substring(Pos2 + 1)
NewBUT.Location = New Point(XLoc, YLoc)
Catch : End Try
AddHandler NewBUT.MouseDown, AddressOf CreatedButtons_Click
AddHandler NewBUT.MouseDown, AddressOf CreatedButtons_MouseDown
AddHandler NewBUT.MouseUp, AddressOf CreatedButtons_MouseUp
CreateButtonX += 1
Next
End If
Timer1.Interval = 1
End Sub
Private Sub CreateNewButton()
NewBUT = New Button
NewBUT.Name = "NewBUT" & ButtonsCount + 1
NewBUT.Parent = Me
NewBUT.Size = New Size(150, 23)
NewBUT.Text = "New created button"
ButtonsCount += 1
End Sub
Private Sub Button1_MouseDown(sender As Object, e As MouseEventArgs) Handles Button1.MouseDown
'Save the current location of 'button1' in its tag before moving it.
Button1.Tag = Button1.Location
'Get the exact location of the cursor on the 'button1'.
XLoc = (Cursor.Position.X - Left - 8) - Button1.Location.X
YLoc = (Cursor.Position.Y - Top - 30) - Button1.Location.Y
Timer1.Start()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
'Move the button while holding down the mouse button.
Button1.Location = New Point(Cursor.Position.X - Left - 8 - XLoc, Cursor.Position.Y - Top - 30 - YLoc)
Timer1.Start()
End Sub
Private Sub Button1_MouseUp(sender As Object, e As MouseEventArgs) Handles Button1.MouseUp
'Stop the movement and create a new button with the same location as 'button1'.
Timer1.Stop()
'Create the new button.
CreateNewButton()
NewBUT.Location = Button1.Location
'Store the location of the duplicated button in the shape of a string array in the Settings with the char "|" as a separator.
If My.Settings.CreatedButtons = "" Then
My.Settings.CreatedButtons &= NewBUT.Name & ":" & NewBUT.Location.X & "," & NewBUT.Location.Y
Else
My.Settings.CreatedButtons &= "|" & NewBUT.Name & ":" & NewBUT.Location.X & "," & NewBUT.Location.Y
End If
My.Settings.Save()
'Add handlers to the duplicated button.
AddHandler NewBUT.MouseDown, AddressOf CreatedButtons_Click
AddHandler NewBUT.MouseDown, AddressOf CreatedButtons_MouseDown
AddHandler NewBUT.MouseUp, AddressOf CreatedButtons_MouseUp
'Return 'button1' to its original location.
Button1.Location = Button1.Tag
End Sub
Private Sub CreatedButtons_Click()
'Your code here when the user presses a created button.
End Sub
Private Sub CreatedButtons_MouseDown()
'Get the exact location of the cursor on the 'clicked button'.
XLoc = (Cursor.Position.X - Left - 8) - ActiveControl.Location.X
YLoc = (Cursor.Position.Y - Top - 30) - ActiveControl.Location.Y
DragedButtonName = ActiveControl.Name
Timer2.Start()
End Sub
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
Controls.Item(DragedButtonName).Location = New Point(Cursor.Position.X - Left - 8 - XLoc, Cursor.Position.Y - Top - 30 - YLoc)
Timer2.Start()
End Sub
Private Sub CreatedButtons_MouseUp()
Timer2.Stop()
'Update the new location of the button based on its name
Dim SelectedButtonPosition As Integer = My.Settings.CreatedButtons.IndexOf(ActiveControl.Name)
Dim SplitSettingsPart1 As String = My.Settings.CreatedButtons.Remove(SelectedButtonPosition)
Dim SplitSettingsPart2 As String = My.Settings.CreatedButtons.Substring(SelectedButtonPosition)
Dim SplitSettingsPart3 As String
If SplitSettingsPart2.Contains("|") Then
SplitSettingsPart3 = SplitSettingsPart2.Substring(SplitSettingsPart2.IndexOf("|"))
End If
SplitSettingsPart2 = SplitSettingsPart2.Remove(SplitSettingsPart2.IndexOf(":"))
SplitSettingsPart2 &= ":" & ActiveControl.Location.X & "," & ActiveControl.Location.Y
My.Settings.CreatedButtons = SplitSettingsPart1 & SplitSettingsPart2 & SplitSettingsPart3
My.Settings.Save()
End Sub
End Class
Try this below, i'v just wrote and it worked perfectly.
Add a timer to your program (Timer1) and then see the code below, i'v also added notes to it to explain everything :
Public Class Form1
Dim XLoc, YLoc As Integer
Private Sub Button1_MouseDown(sender As Object, e As MouseEventArgs) Handles Button1.MouseDown
'Save the current location of 'button1' in its tag before moving it.
Button1.Tag = Button1.Location
'Get the exact location of the cursor on the 'button1'.
XLoc = (Cursor.Position.X - Left - 8) - Button1.Location.X
YLoc = (Cursor.Position.Y - Top - 30) - Button1.Location.Y
Timer1.Start()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
'Move the button while holding down the mouse button.
Button1.Location = New Point(Cursor.Position.X - Left - 8 - XLoc, Cursor.Position.Y - Top - 30 - YLoc)
Timer1.Start()
End Sub
Private Sub Button1_MouseUp(sender As Object, e As MouseEventArgs) Handles Button1.MouseUp
'Stop the movement and create a new button with the same location as 'button1'.
Timer1.Stop()
Dim NewBUT As New Button
NewBUT.Parent = Me
NewBUT.Size = New Size(75, 23)
NewBUT.Text = Button1.Text
NewBUT.Location = Button1.Location
'Return 'button1' to its original location.
Button1.Location = Button1.Tag
End Sub
End Class
To make all the created buttons share the same code, you can do this :
1. Create a function and put all the code you want all the buttons to do when anyone of them is pressed :
Private Sub ButtonClicked()
'Paste here the code.
End Sub
2. When duplicating the button in the old code above, you need to add this line :
AddHandler NewBUT.Click, AddressOf ButtonClicked
So now duplicating the button is like this :
Private Sub Button1_MouseUp(sender As Object, e As MouseEventArgs) Handles Button1.MouseUp
'Stop the movement and create a new button with the same location as 'button1'.
Timer1.Stop()
Dim NewBUT As New Button
NewBUT.Parent = Me
NewBUT.Size = New Size(75, 23)
NewBUT.Text = Button1.Text
NewBUT.Location = Button1.Location
AddHandler NewBUT.Click, AddressOf ButtonClicked
'Return 'button1' to its original location.
Button1.Location = Button1.Tag
End Sub
Hope the will help you :)
Before getting into the code, you need to do some steps, and i will show you these steps using pictures so it will be easier on you.
1.Add an item in the 'Settings' tab to store the locations of the duplicated buttons :
2.The code, this is the whole code for the whole form, i tried to explain as much as i can using comments in the code but if you needed anything, feel free to ask:
Public Class Form1
Dim XLoc, YLoc, CreateButtonX As Integer
Dim CreatedButtons As String()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If My.Settings.CreatedButtons <> "" Then
'Split the string (CreatedButtons) in the Settings with the char "|" as a separator and loop through all the pats when each part is a different location for a duplicated button.
CreatedButtons = My.Settings.CreatedButtons.Split("|")
Dim Separator As String = "|"
For Each Separator In CreatedButtons
Dim NewBUT As New Button
NewBUT.Parent = Me
NewBUT.Size = New Size(75, 23)
NewBUT.Text = "Button 1"
Try
XLoc = CreatedButtons(CreateButtonX).Remove(CreatedButtons(CreateButtonX).IndexOf(","))
YLoc = CreatedButtons(CreateButtonX).Substring(CreatedButtons(CreateButtonX).IndexOf(",") + 1)
NewBUT.Location = New Point(XLoc, YLoc)
Catch : End Try
AddHandler NewBUT.Click, AddressOf ButtonClicked
CreateButtonX += 1
Next
End If
Timer1.Interval = 1
End Sub
Private Sub Button1_MouseDown(sender As Object, e As MouseEventArgs) Handles Button1.MouseDown
'Save the current location of 'button1' in its tag before moving it.
Button1.Tag = Button1.Location
'Get the exact location of the cursor on the 'button1'.
XLoc = (Cursor.Position.X - Left - 8) - Button1.Location.X
YLoc = (Cursor.Position.Y - Top - 30) - Button1.Location.Y
Timer1.Start()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
'Move the button while holding down the mouse button.
Button1.Location = New Point(Cursor.Position.X - Left - 8 - XLoc, Cursor.Position.Y - Top - 30 - YLoc)
Timer1.Start()
End Sub
Private Sub Button1_MouseUp(sender As Object, e As MouseEventArgs) Handles Button1.MouseUp
'Stop the movement and create a new button with the same location as 'button1'.
Timer1.Stop()
'Create the new button.
Dim NewBUT As New Button
NewBUT.Parent = Me
NewBUT.Size = New Size(75, 23)
NewBUT.Text = Button1.Text
NewBUT.Location = Button1.Location
'Store the location of the duplicated button in the shape of a string array in the Settings with the char "|" as a separator.
If My.Settings.CreatedButtons = "" Then
My.Settings.CreatedButtons &= NewBUT.Location.X & "," & NewBUT.Location.Y
Else
My.Settings.CreatedButtons &= "|" & NewBUT.Location.X & "," & NewBUT.Location.Y
End If
My.Settings.Save()
'Add a handler to the duplicated button.
AddHandler NewBUT.Click, AddressOf ButtonClicked
'Return 'button1' to its original location.
Button1.Location = Button1.Tag
End Sub
Private Sub ButtonClicked() Handles Button1.Click
Timer1.Stop() ' THIS IS IMPORTANT!
'Paste your code that you want all the buttons to handel instead of this next line.
MsgBox("Button clicked!")
End Sub
End Class
Hope that helped you, please make sure to vote it up, so i know it did ;)

Re-write dynamic textbox after button is pressed

I've created a code in VBA to collect data using a multi-page control. In each page, I've added checkboxes dynamically based on rows from the worksheet in Excel and, for each checkbox, there's a textbox and 2 command buttons, just like the image below:
Input Window:
The code to automatically add controls is:
Private Sub UserForm_Initialize()
fmat_disp.Value = 0
fmat_set.Value = 0
'---------------------------------------------------------------------------------------------
'Inspeção de Mecânica
Sheets("Mecânica").Activate
n_anom = Application.WorksheetFunction.CountA(Range("1:1")) - 1
AreasInspecao.mecanica.ScrollHeight = 10 + 18 * (n_anom)
For i = 1 To n_anom
'Selecionar anomalia
Set SelAnom = AreasInspecao.mecanica.Controls.Add("Forms.CheckBox.1", "sel_anom_" & i)
SelAnom.Caption = Worksheets("Mecânica").Cells(1, i + 1)
SelAnom.AutoSize = True
SelAnom.Height = 18
SelAnom.Left = 5
SelAnom.Top = 5 + (SelAnom.Height) * (i - 1)
SelAnom.Tag = i
Same goes to the textbox and plus/minus buttons, only changing the captions.
What I want is:
1) when CHECKBOX is CHECKED, respective TEXTBOX must show 1
2) when MINUS sign is PRESSED, respective TEXTBOX must decrement
3) when PLUS sign is PRESSED, respective TEXTBOX must increment
4) when "Finalizar Inspeção" is PRESSED, all data collected must be sent to Excel, filling a worksheet.
I simply don't know how to link each button/checkbox to your respective textbox without creating a subroutine for each one! I'll have ~500 subroutines....that's impossible to manage manually....
OK here's a rough outline for handling the click events on the checkboxes and buttons.
First two custom classes for capturing the clicks: each of these is very simple - all they do is call a method on the userform with the clicked control as an argument.
'clsCheck
Public WithEvents chk As MSForms.CheckBox
Private Sub chk_Click()
frmExample.HandleClick chk
End Sub
'clsButton
Public WithEvents btn As MSForms.CommandButton
Private Sub btn_Click()
frmExample.HandleClick btn
End Sub
Userform code - my form is named "frmExample".
Note the naming convention which allows groups of controls to be treated as a "unit".
Option Explicit
'These two global collections hold instances of the custom classes
Dim colCheckBoxes As Collection
Dim colButtons As Collection
Private Sub UserForm_Activate()
Const CON_HT As Long = 18
Dim x As Long, cbx As MSForms.CheckBox, t
Dim btn As MSForms.CommandButton, txt As MSForms.TextBox
Dim oCheck As clsCheck, oButton As clsButton
Set colCheckBoxes = New Collection
Set colButtons = New Collection
For x = 1 To 10
t = 5 + CON_HT * (x - 1)
Set cbx = Me.Controls.Add("Forms.CheckBox.1", "cbox_" & x)
cbx.Caption = "Checkbox" & x
cbx.Width = 80
cbx.Height = CON_HT
cbx.Left = 5
cbx.Top = t
colCheckBoxes.Add GetCheckHandler(cbx) '<< save in collection
Set btn = Me.Controls.Add("Forms.CommandButton.1", "btnplus_" & x)
btn.Caption = "+"
btn.Height = CON_HT
btn.Width = 20
btn.Left = 90
btn.Top = t
btn.Enabled = False '<<buttons start off disabled
colButtons.Add GetButtonHandler(btn) '<< save in collection
Set btn = Me.Controls.Add("Forms.CommandButton.1", "btnminus_" & x)
btn.Caption = "-"
btn.Height = CON_HT
btn.Width = 20
btn.Left = 130
btn.Top = t
btn.Enabled = False '<<buttons start off disabled
colButtons.Add GetButtonHandler(btn) '<< save in collection
'no events are captured for the textboxes...
Set txt = Me.Controls.Add("Forms.Textbox.1", "txt_" & x)
txt.Width = 30
txt.Height = CON_HT
txt.Left = 170
txt.Top = t
Next x
End Sub
'All "clicked" controls saved in instances of the custom classes
' get passed here. Handle based on control type/name
Public Sub HandleClick(ctrl As MSForms.Control)
Dim num
num = Split(ctrl.Name, "_")(1) 'which set of controls are we working with?
Dim txt As MSForms.TextBox
'get the matching text box...
Set txt = Me.Controls("txt_" & num)
If ctrl.Name Like "cbox_*" Then
If ctrl.Value Then txt.Value = 1
Me.Controls("btnplus_" & num).Enabled = ctrl.Value
Me.Controls("btnminus_" & num).Enabled = ctrl.Value
ElseIf ctrl.Name Like "btnplus_*" Then
txt.Value = txt.Value + 1
ElseIf ctrl.Name Like "btnminus_*" Then
txt.Value = txt.Value - 1
End If
End Sub
'couple of "factory" functions for the event-handling classes
Private Function GetCheckHandler(cb As MSForms.CheckBox)
Dim rv As New clsCheck
Set rv.chk = cb
Set GetCheckHandler = rv
End Function
Private Function GetButtonHandler(btn As MSForms.CommandButton)
Dim rv As New clsButton
Set rv.btn = btn
Set GetButtonHandler = rv
End Function
Sample file: https://www.dropbox.com/s/k74c08m0zkwn9l7/tmpFormEvents.xlsm?dl=0

Working with dynamic event handler in vba

I have created a form where I am dynamically creating Textboxes and corresponding Comboboxes along with Combobox change event. Here is the class creating combobox event handler
Option Explicit
Public WithEvents cbx As MSforms.Combobox
Private avarSplit As Variant
Sub SetCombobox(ctl As MSforms.Combobox)
Set cbx = ctl
End Sub
Private Sub cbx_Change()
Dim i As Integer
If cbx.ListIndex > -1 Then
'MsgBox "You clicked on " & cbx.Name & vbLf & "The value is " & cbx.Value
avarSplit = Split(cbx.Name, "_")
'DecessionOnValue
End If
End Sub
And here is the code on the form which is dynamically creating textboxes and Comboboxes
Function AddTextBox(Frame1 As frame, numberOfColumns As Integer)
Dim counter As Integer
Dim i As Integer
Dim TxtBox As MSforms.TextBox
For counter = 1 To numberOfColumns
'Forms.CommandButton.1
Set TxtBox = Frame1.Controls.Add("Forms.TextBox.1")
TxtBox.Name = "tb_" + CStr(counter)
'Bouton.Caption = "Test"
TxtBox.Visible = True
i = Property.TextBoxDisable(TxtBox)
' Defining coordinates TextBox height is 18
If counter = 1 Then
TxtBox.Top = 23
Else
TxtBox.Top = (18 * counter) + 5 * counter
End If
TxtBox.Left = 50
Next counter
End Function
Function Combobox(Frame1 As frame, numberOfColumns As Integer)
Dim counter As Integer
Dim i As Integer
Dim CbBox As MSforms.Combobox
Dim cbx As ComboWithEvent
If pComboboxes Is Nothing Then Set pComboboxes = New Collection
For counter = 1 To numberOfColumns
'Forms.CommandButton.1
Set CbBox = Frame1.Controls.Add("Forms.ComboBox.1")
CbBox.Name = "cb_" + CStr(counter)
i = AddComboboxValues(CbBox)
' Defining coordinates TextBox height is 18
If counter = 1 Then
CbBox.Top = 23
Else
CbBox.Top = (18 * counter) + 5 * counter
End If
CbBox.Left = 150
Set cbx = New ComboWithEvent
cbx.SetCombobox CbBox
pComboboxes.Add cbx
Next counter
i = AddScrollBar(Frame1, counter)
End Function
Combobox event handler is working fine but my problem is that I dont know that how can I copy the text of textbox or enable disable the textbox according to the value selected in the dynamic combobox.
Thanks,
Jatin
you'll use this for example :
Me.Controls("ControlName").Visible = True or instead of Visible you can use enable, disable etc..

VB6: Splitling with multi-multicharactered delimiters?

I have a problem with the split function I have currently. I am able to either split with 1 delimited only (split()) or split with many single characters (custom()). Is there a way to split this? Keep in mind that these delimiters are not in order.
"MY!!DATA##IS!!LOCATED##HERE!!IN!!BETWEEN##THE##ATS!!AND!!MARKS"
I need your help to get the following result
"MY" , "DATA" , "IS" , "LOCATED" , "HERE" , "IN" , "BETWEEN","THE", "ATS" , "AND", "MARKS"
thanks
Create a new VB6 EXE project and add a button to the form you will be given, and use the following code for the Button1_Click event:
Private Sub Command1_Click()
Dim myText As String
Dim myArray() As String
Dim InBetweenAWord As Boolean
Dim tmpString As String
Dim CurrentCount As Integer
CurrentCount = 0
myText = "MY!!DATA##IS!!LOCATED##HERE!!IN!!BETWEEN##THE##ATS!!AND!!MARKS"
For i = 1 To Len(myText)
If (Mid(myText, i, 1) = "#" Or Mid(myText, i, 1) = "!") And InBetweenAWord = True Then
CurrentCount = CurrentCount + 1
ReDim Preserve myArray(CurrentCount)
myArray(CurrentCount) = tmpString
tmpString = ""
InBetweenAWord = False
Else
If (Mid(myText, i, 1) <> "#" And Mid(myText, i, 1) <> "!") Then
tmpString = tmpString & Mid(myText, i, 1)
InBetweenAWord = True
End If
End If
Next
For i = 1 To CurrentCount
MsgBox myArray(i) 'This will iterate through all of your words
Next
End Sub
Notice that once the first For-Next loop is finished, the [myArray] will contain all of your words without the un-desired characters, so you can use them anywhere you like. I just displayed them as MsgBox to the user to make sure my code worked.
Character handling is really awkward in VB6. I would prefer using built-in functions like this
Private Function MultiSplit(ByVal sText As String, vDelims As Variant) As Variant
Const LNG_PRIVATE As Long = &HE1B6 '-- U+E000 to U+F8FF - Private Use Area (PUA)
Dim vElem As Variant
For Each vElem In vDelims
sText = Replace(sText, vElem, ChrW$(LNG_PRIVATE))
Next
MultiSplit = Split(sText, ChrW$(LNG_PRIVATE))
End Function
Use MultiSplit like this
Private Sub Command1_Click()
Dim vElem As Variant
For Each vElem In MultiSplit("MY!!DATA##IS!!LOCATED##HERE!!IN!!BETWEEN##THE##ATS!!AND!!MARKS", Array("!!", "##"))
Debug.Print vElem
Next
End Sub

Resources