Access a new created line from another sub - vb6

I have some problems accessing informations from a new created element.This is my code
Private Sub c1_Click()
Refresh
Timer1.Enabled = Not Timer1.Enabled
If Timer1.Enabled Then
c1.Caption = "Stop"
Else
c1.Caption = "Start"
End If
a = l.X2 - l.X1
choice = a
End Sub
Private Sub Form_Load()
Dim l As Line
Set l = Controls.Add("VB.Line", "l", Me)
With l
.X1 = 2760
.Y1 = 3000
.X2 = 5640
.Y2 = 3000
.Visible = True
.BorderStyle = 1
.BorderWidth = 2
.BorderColor = vbRed
End With
End Sub
I get an error when i click the button:"Object required".On the form i can see the line but i can't access it from another sub.Where is the problem?

Your Line variable l is private to the Form_Load procedure and goes out of scope.
Move Dim l As Line from Form_Load to the top of your form's code module (outside of any method or function). This will make it available to any method or procedure on your form:
Dim l As Line
Private Sub c1_Click()
Refresh
Timer1.Enabled = Not Timer1.Enabled
If Timer1.Enabled Then
c1.Caption = "Stop"
Else
c1.Caption = "Start"
End If
a = l.X2 - l.X1
choice = a
End Sub
Private Sub Form_Load()
Set l = Controls.Add("VB.Line", "l", Me)
With l
.X1 = 2760
.Y1 = 3000
.X2 = 5640
.Y2 = 3000
.Visible = True
.BorderStyle = 1
.BorderWidth = 2
.BorderColor = vbRed
End With
End Sub

Related

"User-defined type not defined" Error

Hi im trying to create a simple program involving an object and a class within
VB 6.0.
The error message i get is: "User-defined type not defined"
The highlighted code that VB suspects is "Dim Bob As Ball"
My defined class is as follows:
Dim Bob As Object
Public Sub Ball()
Dim Circlex As Integer
Dim Circley As Integer
Public Sub makeBall()
Circlex = 3000
Circley = 3000
End Sub
Private Sub moveBall()
Circle (Circlex, Circley), 200
End Sub
End Sub
My code for the only form in my project is:
Private Sub Command1_Click()
Command1.Visible = False
Command1.Enabled = False
vbalProgressBar1.Visible = True
Timer1.Enabled = True
Beep
End Sub
Private Sub Form_Load()
Form1.Width = 6000
Form1.Height = 6000
Dim Bob As Ball
Dim Bob As New Ball
End Sub
Private Sub Form_Unload(Cancel As Integer)
If MsgBox("Are you sure you want to be a quitter?!"
, vbYesNo,"Quit?") = vbYes Then
Unload Me
Set Form1 = Nothing
Else
Cancel = 1
End If
End Sub
Private Sub Timer1_Timer()
Bob = moveBall(Circlex, Circley)
End Sub
Im not sure why the suspected line of code is incorrect, but any help would be appreciated!
VB6 doesn't use code style that you coded.
You have to follow these method to make code work with your intention.
1. make classmodule
2. set its name 'Ball'
3. paste this code on classmodule
Dim Circlex As Integer
Dim Circley As Integer
Public Sub makeBall()
Circlex = 3000
Circley = 3000
End Sub
Private Sub moveBall()
Circle (Circlex, Circley), 200
End Sub
paste code on your form
Private Sub Command1_Click()
Command1.Visible = False
Command1.Enabled = False
vbalProgressBar1.Visible = True
Timer1.Enabled = True
Beep
End Sub
Private Sub Form_Load()
Form1.Width = 6000
Form1.Height = 6000
Dim Bob As New Ball
End Sub
Private Sub Form_Unload(Cancel As Integer)
If MsgBox("Are you sure you want to be a quitter?!"
, vbYesNo,"Quit?") = vbYes Then
Unload Me
Set Form1 = Nothing
Else
Cancel = 1
End If
End Sub
Private Sub Timer1_Timer()
Bob.moveBall(Circlex, Circley)
End Sub
Additionally, VB6 doesn't support style like
Sub A()
Sub B()
End Sub
End Sub

Serial Communication in VB6

I am new with vb6 and communication app, I try to run a example that transmitting and receiving data between two serial ports ( I install two serial ports by com0com soft).
In this example, I want User to type charracters in textbox1, then click command button, and charracters in textbox1 display in textbox2.
Private Sub Command1_Click()
com1.Output = Text1.Text
End Sub
Private Sub Form_Load()
com1.CommPort = 1
com1.Settings = "9600,n,8,1"
com1.PortOpen = True
com2.CommPort = 2
com2.Settings = "9600,n,8,1"
com2.PortOpen = True
Text1.Text = ""
Text2.Text = ""
End Sub
Private Sub com2_OnComm()
If com2.CommEvent = comEvReceive Then
Text2.Text = Text2.Text + com2.Input
End If
End Sub
I screened form in the example and setting in com0com port, I don't have enought reputation to post image, so I upload this to flickr.
http://farm8.staticflickr.com/7627/16740707238_6b1d9ec3ab_b.jpg
But when I try to run this example by type charracters in textbox1 and click button, nothing happen.
So what am I doing wrong?. If so, how can I do to get data from com1 port to com2port? Or any advice for anything!
thanks for reading !
I think you need to look a little harder at the documentation.
Here's a minimal example where COM3/COM4 are the looped ports on my machine:
Option Explicit
Private Sub Command1_Click()
If Len(Text1.Text) > 0 Then
MSComm1.Output = Text1.Text
Text1.Text = vbNullString
End If
Text1.SetFocus
End Sub
Private Sub Form_Load()
With MSComm1
.CommPort = 3
.Settings = "256000,n,8,1"
.Handshaking = comNone
.SThreshold = 0 'No events after send completions.
.RThreshold = 0 'No events after receive completions.
.PortOpen = True
End With
With MSComm2
.CommPort = 4
.Settings = "256000,n,8,1"
.EOFEnable = False
.Handshaking = comNone
.InputMode = comInputModeText
.RThreshold = 1 'Event for each character received. Terribly
'inefficient but if char-by-char events are
'required there isn't much choice.
.SThreshold = 0 'No events after send completions.
.PortOpen = True
End With
End Sub
Private Sub Form_Unload(Cancel As Integer)
MSComm1.PortOpen = False
MSComm2.PortOpen = False
End Sub
Private Sub MSComm2_OnComm()
With MSComm2
If .CommEvent = comEvReceive Then
.InputLen = 0
Text2.SelStart = &H7FFF
Text2.SelText = .Input
End If
End With
End Sub

Mouse Move Handle on a ListBox

I have a ListBox on which I want to handle the mousemove event; And for that reason I'm using the following code
Private Sub AreaLB_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles AreaLB.MouseMove
Dim ListMousePosition As Point = AreaLB.PointToClient(Me.MousePosition)
Dim itemIndex As Integer = AreaLB.IndexFromPoint(ListMousePosition)
Dim AreaToolTip As ToolTip = ToolTip1
Dim myLB As ListBox = AreaLB
AreaToolTip.Active = True
Dim g As Graphics = AreaLB.CreateGraphics()
If itemIndex > -1 Then
Dim s As String = myLB.Items(itemIndex)
If g.MeasureString(s, myLB.Font).Width > myLB.ClientRectangle.Width Then
AreaToolTip.SetToolTip(myLB, s)
Else
AreaToolTip.SetToolTip(myLB, "")
End If
g.Dispose()
End If
End Sub
My problem is... When I'm not moving the mouse this procedure runs always when the
g.MeasureString(s, myLB.Font).Width > myLB.ClientRectangle.Width
Why that happens and how can I avoid it.
What you can do is only set the ToolTip if it isn't already the value you want it to be:
Private Sub AreaLB_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles AreaLB.MouseMove
ToolTip1.Active = True
Dim itemIndex As Integer = AreaLB.IndexFromPoint(e.X, e.Y)
If itemIndex > -1 Then
Using g As Graphics = AreaLB.CreateGraphics()
Dim s As String = AreaLB.Items(itemIndex)
If g.MeasureString(s, AreaLB.Font).Width > AreaLB.ClientRectangle.Width Then
If ToolTip1.GetToolTip(AreaLB) <> s Then
ToolTip1.Show(s, AreaLB)
End If
Else
ToolTip1.Show("", AreaLB)
End If
End Using
End If
End Sub

I want to send data and receive data as string if possible or at least as integer

I am trying to send and receive data through mscomm port, but am receiving datatype mismatch.so what should I do to avoid this error, I need to send data as integer and receive it as string if possible ,minimum I should get it as integer datatype. The following is my code, please help me to solve this problem.
The send and receive code is working when run independently.
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Sub Command1_Click()
If (MSComm1.PortOpen = False) Then
MSComm1.PortOpen = True
End If
Command1.Enabled = False
Command2.Enabled = True
Text3.Text = "COM1, Baud - 9600, Databit - 8, Parity - None, Stopbit - 1....CONNECTED." & Text3.Text
End Sub
Private Sub Command2_Click()
If (MSComm1.PortOpen = True) Then
MSComm1.PortOpen = False
End If
Command1.Enabled = True
Command2.Enabled = False
Text3.Text = "DISCONNECTED" & Text3.Text
End Sub
Private Sub Command3_Click()
Text1.Text = " "
Text2.Text = " "
Text3.Text = "CLEARED" & Text3.Text
End Sub
Private Sub Command4_Click()
MSComm1.Output = Text2.Text
Text3.Text = "SENDING" & Text3.Text
End Sub
Private Sub Command5_Click()
Text3.Text = " "
End Sub
Private Sub Form_Load()
MSComm1.CommPort = 1
MSComm1.Settings = "9600,N,8,1"
MSComm1.DTREnable = True
MSComm1.Handshaking = comRTS
MSComm1.InBufferSize = 2
MSComm1.RThreshold = MSComm1.InBufferSize
MSComm1.RTSEnable = True
MSComm1.InputLen = 2
MSComm1.InputMode = comInputModeText
MSComm1.NullDiscard = True
MSComm1.OutBufferSize = 2
MSComm1.SThreshold = MSComm1.OutBufferSize
MSComm1.PortOpen = True
End Sub
Private Sub Form_Unload(Cancel As Integer)
If (MSComm1.PortOpen = True) Then
MSComm1.PortOpen = False
End If
End Sub
Private Sub MSComm1_OnComm()
Dim Buffer As String
Select Case MSComm1.CommEvent
Case comEvReceive
'Text1.Text = " "
Buffer = Cstr(MSComm1.Input)
Text1.Text = Buffer
End Select
End Sub
I think the main problem is that you are sending data asynchroniously without any attempt to transmission control. Since there are multiple characters to be transmitted you need to tell the receiver where a new transmission start to let it find the right offset.
In your case you say you only want to send values in the range 0..100. By using a single byte values in the range 0 to 255 can be addressed so sending a single byte per value to send is sufficient in that case and for a single character no transnission control will be necessary.
Here an example where the number is converted to a single byte, send and reconverted to a number:
Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Sub cmdOpen_Click()
If (MSComm1.PortOpen = False) Then
MSComm1.PortOpen = True
End If
cmdOpen.Enabled = False
cmdClose.Enabled = True
txtState.Text = "COM1, Baud - 9600, Databit - 8, Parity - None, Stopbit - 1....CONNECTED." & txtState.Text
End Sub
Private Sub cmdClose_Click()
If (MSComm1.PortOpen = True) Then
MSComm1.PortOpen = False
End If
cmdOpen.Enabled = True
cmdClose.Enabled = False
txtState.Text = "DISCONNECTED" & txtState.Text
End Sub
Private Sub cmdClear_Click()
txtReceived.Text = " "
txtSend.Text = " "
txtState.Text = "CLEARED" & txtState.Text
End Sub
Private Sub cmdSend_Click()
Dim Number As Byte
'some checking - needed depending on source of data
If Not IsNumeric(txtSend.Text) Then
MsgBox "only numbers (from 0 to 255)"
Exit Sub
End If
If Val(txtSend.Text) < 0 Or Val(txtSend.Text) > 255 Then
MsgBox "out of range (from 0 to 255)"
Exit Sub
End If
Number = CByte(Val(txtSend.Text))
MSComm1.Output = Chr(Number)
txtState.Text = "SENDING" & txtState.Text
End Sub
Private Sub cmdClearState_Click()
txtState.Text = " "
End Sub
Private Sub Form_Load()
MSComm1.CommPort = 1
MSComm1.Settings = "9600,N,8,1"
MSComm1.DTREnable = True
MSComm1.Handshaking = comNone 'comRTS i only got a 3-wire connection - so no handshaking
MSComm1.InBufferSize = 1024 'not 2 we don't want a buffer overflow THAT fast
MSComm1.RThreshold = 1 'Raise OnComm-Event if 1 character is in Rx-buffer
MSComm1.RTSEnable = True
MSComm1.InputLen = 1 'get one character at a time
MSComm1.InputMode = comInputModeText 'the Binary mode never worked out for me - even when transmitting binary data
MSComm1.NullDiscard = False 'also NULL-Characters will be received
MSComm1.OutBufferSize = 512 'again we don't want overflow
MSComm1.SThreshold = 0 'don't hold back data - blow them out directly
MSComm1.PortOpen = True
End Sub
Private Sub Form_Unload(Cancel As Integer)
If (MSComm1.PortOpen = True) Then
MSComm1.PortOpen = False
End If
End Sub
Private Sub MSComm1_OnComm()
Dim Buffer As String
Select Case MSComm1.CommEvent
Case comEvReceive
'txtReceived.Text = " "
Buffer = MSComm1.Input
txtReceived.Text = Asc(Buffer)
txtState.Text = "RX" + txtState.Text
End Select
End Sub

How to add events to Controls created at runtime in Excel with VBA

I would like to add a Control and an associated event at runtime in Excel using VBA but I don't know how to add the events.
I tried the code below and the Button is correctly created in my userform but the associated click event that should display the hello message is not working.
Any advice/correction would be welcome.
Dim Butn As CommandButton
Set Butn = UserForm1.Controls.Add("Forms.CommandButton.1")
With Butn
.Name = "CommandButton1"
.Caption = "Click me to get the Hello Message"
.Width = 100
.Top = 10
End With
With ThisWorkbook.VBProject.VBComponents("UserForm1.CommandButton1").CodeModule
Line = .CountOfLines
.InsertLines Line + 1, "Sub CommandButton1_Click()"
.InsertLines Line + 2, "MsgBox ""Hello!"""
.InsertLines Line + 3, "End Sub"
End With
UserForm1.Show
The code for adding a button at runtime and then to add events is truly as simple as it is difficult to find out. I can say that because I have spent more time on this perplexity and got irritated more than in anything else I ever programmed.
Create a Userform and put in the following code:
Option Explicit
Dim ButArray() As New Class2
Private Sub UserForm_Initialize()
Dim ctlbut As MSForms.CommandButton
Dim butTop As Long, i As Long
'~~> Decide on the .Top for the 1st TextBox
butTop = 30
For i = 1 To 10
Set ctlbut = Me.Controls.Add("Forms.CommandButton.1", "butTest" & i)
'~~> Define the TextBox .Top and the .Left property here
ctlbut.Top = butTop: ctlbut.Left = 50
ctlbut.Caption = Cells(i, 7).Value
'~~> Increment the .Top for the next TextBox
butTop = butTop + 20
ReDim Preserve ButArray(1 To i)
Set ButArray(i).butEvents = ctlbut
Next
End Sub
Now you need to add a Class Module to your code for the project. Please remember it's class module, not Standard Module.
The Object butEvents is the button that was clicked.
Put in the following simple code (in my case the class name is Class2).
Public WithEvents butEvents As MSForms.CommandButton
Private Sub butEvents_click()
MsgBox "Hi Shrey from " & butEvents.Caption
End Sub
That's it. Now run it!
Try this:
Sub AddButtonAndShow()
Dim Butn As CommandButton
Dim Line As Long
Dim objForm As Object
Set objForm = ThisWorkbook.VBProject.VBComponents("UserForm1")
Set Butn = objForm.Designer.Controls.Add("Forms.CommandButton.1")
With Butn
.Name = "CommandButton1"
.Caption = "Click me to get the Hello Message"
.Width = 100
.Top = 10
End With
With objForm.CodeModule
Line = .CountOfLines
.InsertLines Line + 1, "Sub CommandButton1_Click()"
.InsertLines Line + 2, "MsgBox ""Hello!"""
.InsertLines Line + 3, "End Sub"
End With
VBA.UserForms.Add(objForm.Name).Show
End Sub
This permanently modifies UserForm1 (assuming you save your workbook). If you wanted a temporary userform, then add a new userform instead of setting it to UserForm1. You can then delete the form once you're done with it.
Chip Pearson has some great info about coding the VBE.
DaveShaw, thx for this code man!
I have used it for a togglebutton array (put a 'thumbnail-size' picture called trainer.jpg in the same folder as the excel file for a togglebutton with a picture in it). In the 'click' event the invoker is also available (by the object name as a string)
In the form:
Dim CreateTrainerToggleButtonArray() As New ToggleButtonClass
Private Sub CreateTrainerToggleButton(top As Integer, id As Integer)
Dim pathToPicture As String
pathToPicture = ThisWorkbook.Path & "\trainer.jpg"
Dim idString As String
idString = "TrainerToggleButton" & id
Dim cCont As MSForms.ToggleButton
Set cCont = Me.Controls.Add _
("Forms.ToggleButton.1")
With cCont
.Name = idString
.Width = 20
.Height = 20
.Left = 6
.top = top
.picture = LoadPicture(pathToPicture)
End With
ReDim Preserve CreateTrainerToggleButtonArray(1 To id)
Set CreateTrainerToggleButtonArray(id).ToggleButtonEvents = cCont
CreateTrainerToggleButtonArray(id).ObjectName = idString
End Sub
and a class "ToggleButtonClass"
Public WithEvents ToggleButtonEvents As MSForms.ToggleButton
Public ObjectName As String
Private Sub ToggleButtonEvents_click()
MsgBox "DaveShaw is the man... <3 from your friend: " & ObjectName
End Sub
Now just simple call from UserForm_Initialize
Private Sub UserForm_Initialize()
Dim index As Integer
For index = 1 To 10
Call CreateTrainerToggleButton(100 + (25 * index), index)
Next index
End Sub
This was my solution to add a commandbutton and code without using classes
It adds a reference to allow access to vbide
Adds the button
Then writes a function to handle the click event in the worksheet
Sub AddButton()
Call addref
Set rng = DestSh.Range("B" & x + 3)
'Set btn = DestSh.Buttons.Add(rng.Left, rng.Top, rng.Width, rng.Height)
Set myButton = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", Left:=rng.Left, Top:=rng.Top, Height:=rng.Height * 3, Width:=rng.Width * 3)
DoEvents
With myButton
'.Placement = XlPlacement.xlFreeFloating
.Object.Caption = "Export"
.Name = "BtnExport"
.Object.PicturePosition = 1
.Object.Font.Size = 14
End With
Stop
myButton.Object.Picture = LoadPicture("F:\Finalised reports\Templates\Macros\evolution48.bmp")
Call CreateButtonEvent
End Sub
Sub addref()
On Error Resume Next
Application.VBE.ActiveVBProject.References.AddFromFile "C:\Program Files (x86)\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
Application.VBE.ActiveVBProject.References.AddFromFile "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
End Sub
Private Sub CreateButtonEvent()
On Error GoTo errtrap
Dim oXl As Application: Set oXl = Application
oXl.EnableEvents = False
oXl.DisplayAlerts = False
oXl.ScreenUpdating = False
oXl.VBE.MainWindow.Visible = False
Dim oWs As Worksheet
Dim oVBproj As VBIDE.VBProject
Dim oVBcomp As VBIDE.VBComponent
Dim oVBmod As VBIDE.CodeModule '
Dim lLine As Single
Const QUOTE As String = """"
Set oWs = Sheets("Contingency")
Set oVBproj = ThisWorkbook.VBProject
Set oVBcomp = oVBproj.VBComponents(oWs.CodeName)
Set oVBmod = oVBcomp.CodeModule
With oVBmod
lLine = .CreateEventProc("Click", "BtnExport") + 1
.InsertLines lLine, "Call CSVFile"
End With
oXl.EnableEvents = True
oXl.DisplayAlerts = True
Exit Sub
errtrap:
End Sub
An easy way to do it:
1 - Insert a class module and write this code:
Public WithEvents ChkEvents As MSForms.CommandButton
Private Sub ChkEvents_click()
MsgBox ("Click Event")
End Sub
2 - Insert a userform and write this code:
Dim Chk As New Clase1
Private Sub UserForm_Initialize()
Dim NewCheck As MSForms.CommandButton
Set NewCheck = Me.Controls.Add("Forms.CommandButton.1")
NewCheck.Caption = "Prueba"
Set Chk.ChkEvents = NewCheck
End Sub
Now show the form and click the button
I think the code needs to be added to the Userform, not to the button itself.
So something like
With UserForm1.CodeModule
'Insert code here
End With
In place of your With ThisWorkbook

Resources