this isn't triggering when it should.
vb Code:
Public Const BatchStartPosition As Double = 11242.11 picBatch(Index).Left = 11242.11 If BatchStartPosition = picBatch(i).Left Then MsgBox ("Batch is in start position.") End If
Printable View
this isn't triggering when it should.
vb Code:
Public Const BatchStartPosition As Double = 11242.11 picBatch(Index).Left = 11242.11 If BatchStartPosition = picBatch(i).Left Then MsgBox ("Batch is in start position.") End If
The problem is the decimals: the Left property is expressed in twips which is an Integer (actually a Long).Quote:
Originally Posted by TheUsed
Try 11242 and it'll work.
Assuming that picBatch is a control, it actually shouldn't trigger - as that is not a valid value for .Left (so it gets rounded to the nearest valid position).
have you put a break point to see what is happening?
what sub is this called in?
i believe that positions of controls are set to the nearest appropriate value
Code:Picture1.Left=11242.11
?Picture1.Left
11242
Quote:
For a form, the Left and Top properties are always expressed intwips; for a control, they are measured in units depending on the coordinate system of its container. The values for these properties change as the object is moved by the user or by code. For the CommonDialog and Timer controls, these properties aren't available atrun time.
For either property, you can specify a single-precision number.
okay here is a list of everything I tried before I posted.
I created a picturebox on my form and set it where I wanted my button "add batch" to create a batch. I took the left property of it and inserted it in my code. I thought it was weird I got a .11 at the end.
After several tries I have set debug.prints to print the left position of the batch. it shows it as 11242.11
I have changed BatchStartPosition to a double, single, long, integer.
Never triggers. That is unless I set this... to <
vb Code:
If BatchStartPosition = picBatch(i).Left Then MsgBox ("Batch is in start position.") End If
here is the code of the entire project
vb Code:
Option Explicit Private Sub cmdAddBatch_Click() intControlIndex = UBound(picBatch) + 1 ReDim Preserve picBatch(intControlIndex) Set picBatch(intControlIndex) = Controls.Add("VB.PictureBox", "PicBatch_" & CStr(intControlIndex)) Call ADD_BATCH(intControlIndex) End Sub Private Sub cmdStart_Click() If UBound(picBatch) = 0 Then MsgBox "You need to add a batch.", vbExclamation, "Batch Required" Exit Sub Else Call Initialize_Movement End If 'Timer1.Enabled = True End Sub Private Sub cmdStop_Click() Timer1.Enabled = False End Sub Private Sub Form_Load() intControlIndex = 0 ReDim Preserve picBatch(intControlIndex) End Sub Private Sub Timer1_Timer() Call Collide End Sub MODULE CODE: Option Explicit Public i As Integer Public picBatch() As PictureBox Public intControlIndex As Integer Public Const BatchStartPosition As Double = 11242.11 Public Sub ADD_BATCH(Index As Integer) picBatch(Index).Height = 840 picBatch(Index).Width = 630 picBatch(Index).Top = 900 picBatch(Index).Left = 11242.11 picBatch(Index).Picture = LoadPicture(App.Path & "\batch.bmp") picBatch(Index).Visible = True Debug.Print picBatch(Index).Left End Sub Public Sub Initialize_Movement() Debug.Print picBatch(1).Left For i = UBound(picBatch) To LBound(picBatch) + 1 Step -1 If BatchStartPosition = picBatch(i).Left Then MsgBox ("Batch is in start position.") End If Next i End Sub Public Sub Collide() Dim Index As Integer If frmLaser.Timer1.Enabled = False Then Exit Sub End If For Index = UBound(picBatch) To LBound(picBatch) Step -1 'as Variant in picbatch If UBound(picBatch) <= 1 Then _ Exit Sub For i = 1 To intControlIndex Step 1 If i = Index Then GoTo MOVE_ON If picBatch(Index).Left = picBatch(i).Left Then MsgBox ("We have " & picBatch(Index).Name & " collided with " & picBatch(i).Name) Index = Index - 1 End If MOVE_ON: 'USED TO MOVE TO THE NEXT I IF i= Index Next i Next Index End Sub
What are the actual values of BatchStartPosition and picBatch(i).Left when you reach the If statement?
Note that there are very few times that GoTo is a good idea (many people say never), and how you used it is not apt.. instead of having this:
it would make more sense (and be more readable) to have this:Code:If i = Index Then GoTo MOVE_ON
...
MOVE_ON:
Code:If i <> Index Then
...
End if
the actual values are the exact same. picbatch(i).left DOES EQUAL BatchStartPosition
that is 11242.11
from the information in all the replys here, why do you not change your constant to an integer (whole number, no decimal places) then your code should work
if you can not do that then round your values when you test like
if picture1.left = round(batchstartposition, 0) then
I did take it to a whole number as well, made it 11242 sorry I didn't say I did..
I have no idea why it's not triggering the IF THEN event. the debug line checks for it then just goes right to end sub.
There is the image of debugging and getting the values then the yellow highlighted line is showing the next step from where the break point is set.
I resolved it by rounding it 2 numbers past the decimal. I only knew to do that because I finally got a mismatched value
however, why wouldn't it trigger while getting the same values..
this is the updated code.
vb Code:
Public Sub Initialize_Movement() Debug.Print picBatch(1).Left For i = intControlIndex To 1 Step -1 Debug.Print "CDbl(frmLaser.Line9.X1): " & CDbl(frmLaser.Line9.X1) & vbCrLf & "CDbl(BatchStartPosition): " & CDbl(BatchStartPosition) If CDbl(BatchStartPosition) = Round(CDbl(frmLaser.Line9.X1), 2) Then MsgBox ("Batch is in start position.") End If Next i
You've found a common issue with Double and Single.. they aren't particularly accurate (and like with Date values are not actually displayed the same way they are stored), so you need a certain level of rounding to match numbers that seem to be identical. Note that it needs to be done for both sides of the comparison, so your check should be like this:
(there is no need for CDbl there, as the variable is a Double already)Code:If Round(BatchStartPosition,2) = Round(CDbl(frmLaser.Line9.X1), 2) Then
Note that this issue would be less likely to happen if you had declared BatchStartPosition with the same data type as the things you are storing it to and comparing it to (so Single), but you should still use rounding to be safe.