Loops causing my program to crash (Visual Basic) - vb.net

I'm newish to VB and I'm having some issues. I'm using Repeat Until loops and my program is just crashing if I try to put anything of minor complexity in. I'm generating random numbers. I've isolated the issue to the following loop, and have removed other code that doesn't effect it.
ShowNO, Hidden, C, CA, R, RA, B, BA and all the B11 etc. values are defined as integers.
Hidden is confined to the range 11-19 in the HSB, so that aint the issue
Hidden = hsbDifficulty.Value * -1
If (Hidden = 11 Or 12) Then
RA = 5
CA = 5
BA = 5
End If
If (Hidden = 13 Or 14) Then
RA = 5
CA = 5
BA = 6
End If
If (Hidden = 15 Or 16 Or 17) Then
RA = 5
CA = 6
BA = 6
End If
If (Hidden = 18 Or 19) Then
RA = 6
CA = 6
BA = 6
End If
Randomize()
Do
Do
ShowNO = (Rnd() * 36)
Select Case ShowNO
Case Is = 0
B66 = 1
Case Is = 1
B11 = 1
Case Is = 2
B12 = 1
Case Is = 3
B13 = 1
Case Is = 4
B14 = 1
Case Is = 5
B15 = 1
Case Is = 6
B16 = 1
Case Is = 7
B21 = 1
Case Is = 8
B22 = 1
Case Is = 9
B23 = 1
Case Is = 10
B24 = 1
Case Is = 11
B25 = 1
Case Is = 12
B26 = 1
Case Is = 13
B31 = 1
Case Is = 14
B32 = 1
Case Is = 15
B33 = 1
Case Is = 16
B34 = 1
Case Is = 17
B35 = 1
Case Is = 18
B36 = 1
Case Is = 19
B41 = 1
Case Is = 20
B42 = 1
Case Is = 21
B43 = 1
Case Is = 22
B44 = 1
Case Is = 23
B45 = 1
Case Is = 24
B46 = 1
Case Is = 25
B51 = 1
Case Is = 26
B52 = 1
Case Is = 27
B53 = 1
Case Is = 28
B54 = 1
Case Is = 29
B55 = 1
Case Is = 30
B56 = 1
Case Is = 31
B61 = 1
Case Is = 32
B62 = 1
Case Is = 33
B63 = 1
Case Is = 34
B64 = 1
Case Is = 35
B65 = 1
Case Is = 36
B66 = 1
End Select
Loop Until (B11 + B12 + B13 + B14 + B15 + B16 + B21 + B22 + B23 + B24 + B25 + B26 + B31 + B32 + B33 + B34 + B35 + B36 + B41 + B42 + B43 + B44 + B45 + B46 + B51 + B52 + B53 + B54 + B55 + B56 + B61 + B62 + B63 + B64 + B65 + B66 = Hidden)
If (B11 + B12 + B13 + B14 + B15 + B16 > 0.9) Then
R = R + 1
End If
If (B21 + B22 + B23 + B24 + B25 + B26 > 0.9) Then
R = R + 1
End If
If (B31 + B32 + B33 + B34 + B35 + B36 > 0.9) Then
R = R + 1
End If
If (B41 + B42 + B43 + B44 + B45 + B46 > 0.9) Then
R = R + 1
End If
If (B51 + B52 + B53 + B54 + B55 + B56 > 0.9) Then
R = R + 1
End If
If (B61 + B62 + B63 + B64 + B65 + B66 > 0.9) Then
R = R + 1
End If
If (B11 + B21 + B31 + B41 + B51 + B61 > 0.9) Then
C = C + 1
End If
If (B12 + B22 + B32 + B42 + B52 + B62 > 0.9) Then
C = C + 1
End If
If (B13 + B23 + B33 + B43 + B53 + B63 > 0.9) Then
C = C + 1
End If
If (B14 + B24 + B34 + B44 + B54 + B64 > 0.9) Then
C = C + 1
End If
If (B15 + B25 + B35 + B45 + B55 + B65 > 0.9) Then
C = C + 1
End If
If (B16 + B26 + B36 + B46 + B56 + B66 > 0.9) Then
C = C + 1
End If
If (B11 + B12 + B13 + B21 + B22 + B23 > 0.9) Then
B = B + 1
End If
If (B31 + B32 + B33 + B41 + B42 + B43 > 0.9) Then
B = B + 1
End If
If (B51 + B52 + B53 + B61 + B62 + B63 > 0.9) Then
B = B + 1
End If
If (B14 + B15 + B16 + B24 + B25 + B26 > 0.9) Then
B = B + 1
End If
If (B34 + B35 + B36 + B44 + B45 + B46 > 0.9) Then
B = B + 1
End If
If (B54 + B55 + B56 + B64 + B65 + B66 > 0.9) Then
B = B + 1
End If
Loop Until (B > (BA - 1) And C > (CA - 1) And R > (RA - 1))

If you read the Documentation for Select Case in VB .Net, you will find out that you are doint it wrong :
Select Case ShowNo
'Use Case 0 Instead of Case Is = 0
Case 0
'Do some Stuff
End Select
Also, as mentionned by nabuchodonossor, the If at the begginning are not good :
'Proper way to write this :
If Hidden = 11 Or Hidden = 12 Then
Also, if you can give us the Exception that you encouter, we might be able to help you better.

Re-jigged the whole thing to an array which fixed the problem. Likely the huge amount of variables that made it crash. Thanks for the assistance.

Related

How to reduce case in VB Net?

Can this code be somewhat shorter? values change from 10 in 10 cases to +1, as follows as follows. For each textbox, I have these 80 cases, and I have a total of 30 textboxes and the code is too long. Once again I have to repeat the code, because aryText = TextNSt1.Text.Split ("," c) - up to aryText = TextNSt30.Text.Split ("," c) - so 30 times you code this, and I do not really like it, comma, the code is too long. The code changes with +1 in the following cases from Case 1 to 10, Cases 11-20, Cases 21-30, Cases 31-40, Cases 41-50, Cases 51-60, Cases 61-70, 71- 80...
Dim i As Integer
Dim aryText() As String
'SPLIT THE TEXT INTO AN ARRAY'
aryText = TextNSt2.Text.Split(","c)
For i = 0 To UBound(aryText)
Select Case aryText(i)
Case "1"
LbNxSt1.Text = Val(LbNxSt1.Text) + 1
txtS10.Text = Val(txtS10.Text) + 1
txtDrawB1.Text = Val(txtDrawB1.Text) + 1
Case "2"
LbNxSt2.Text = Val(LbNxSt2.Text) + 1
txtS10.Text = Val(txtS10.Text) + 2
txtDrawB1.Text = Val(txtDrawB1.Text) + 1
Case "3"
LbNxSt3.Text = Val(LbNxSt3.Text) + 1
txtS10.Text = Val(txtS10.Text) + 3
txtDrawB1.Text = Val(txtDrawB1.Text) + 1
Case "4"
LbNxSt4.Text = Val(LbNxSt4.Text) + 1
txtS10.Text = Val(txtS10.Text) + 4
txtDrawB1.Text = Val(txtDrawB1.Text) + 1
Case "5"
LbNxSt5.Text = Val(LbNxSt5.Text) + 1
txtS10.Text = Val(txtS10.Text) + 5
txtDrawB1.Text = Val(txtDrawB1.Text) + 1
Case "6"
LbNxSt6.Text = Val(LbNxSt6.Text) + 1
txtS10.Text = Val(txtS10.Text) + 6
txtDrawB1.Text = Val(txtDrawB1.Text) + 1
Case "7"
LbNxSt7.Text = Val(LbNxSt7.Text) + 1
txtS10.Text = Val(txtS10.Text) + 7
txtDrawB1.Text = Val(txtDrawB1.Text) + 1
Case "8"
LbNxSt8.Text = Val(LbNxSt8.Text) + 1
txtS10.Text = Val(txtS10.Text) + 8
txtDrawB1.Text = Val(txtDrawB1.Text) + 1
Case "9"
LbNxSt9.Text = Val(LbNxSt9.Text) + 1
txtS10.Text = Val(txtS10.Text) + 9
txtDrawB1.Text = Val(txtDrawB1.Text) + 1
Case "10"
LbNxSt10.Text = Val(LbNxSt10.Text) + 1
txtS10.Text = Val(txtS10.Text) + 10
txtDrawB1.Text = Val(txtDrawB1.Text) + 1
Case "11"
LbNxSt11.Text = Val(LbNxSt11.Text) + 1
txtS20.Text = Val(txtS20.Text) + 1
txtDrawB2.Text = Val(txtDrawB2.Text) + 1
Case "12"
LbNxSt12.Text = Val(LbNxSt12.Text) + 1
txtS20.Text = Val(txtS20.Text) + 2
txtDrawB2.Text = Val(txtDrawB2.Text) + 1
Case "13"
LbNxSt13.Text = Val(LbNxSt13.Text) + 1
txtS20.Text = Val(txtS20.Text) + 3
txtDrawB2.Text = Val(txtDrawB2.Text) + 1
Case "14"
LbNxSt14.Text = Val(LbNxSt14.Text) + 1
txtS20.Text = Val(txtS20.Text) + 4
txtDrawB2.Text = Val(txtDrawB2.Text) + 1
Case "15"
LbNxSt15.Text = Val(LbNxSt15.Text) + 1
txtS20.Text = Val(txtS20.Text) + 5
txtDrawB2.Text = Val(txtDrawB2.Text) + 1
Case "16"
LbNxSt16.Text = Val(LbNxSt16.Text) + 1
txtS20.Text = Val(txtS20.Text) + 6
txtDrawB2.Text = Val(txtDrawB2.Text) + 1
Case "17"
LbNxSt17.Text = Val(LbNxSt17.Text) + 1
txtS20.Text = Val(txtS20.Text) + 7
txtDrawB2.Text = Val(txtDrawB2.Text) + 1
Case "18"
LbNxSt18.Text = Val(LbNxSt18.Text) + 1
txtS20.Text = Val(txtS20.Text) + 8
txtDrawB2.Text = Val(txtDrawB2.Text) + 1
Case "19"
LbNxSt19.Text = Val(LbNxSt19.Text) + 1
txtS20.Text = Val(txtS20.Text) + 9
txtDrawB2.Text = Val(txtDrawB2.Text) + 1
Case "20"
LbNxSt20.Text = Val(LbNxSt20.Text) + 1
txtS20.Text = Val(txtS20.Text) + 10
txtDrawB2.Text = Val(txtDrawB2.Text) + 1
Case "21"
LbNxSt21.Text = Val(LbNxSt21.Text) + 1
txtS30.Text = Val(txtS30.Text) + 1
txtDrawB3.Text = Val(txtDrawB3.Text) + 1
Case "22"
LbNxSt22.Text = Val(LbNxSt22.Text) + 1
txtS30.Text = Val(txtS30.Text) + 2
txtDrawB3.Text = Val(txtDrawB3.Text) + 1
Case "23"
LbNxSt23.Text = Val(LbNxSt23.Text) + 1
txtS30.Text = Val(txtS30.Text) + 3
txtDrawB3.Text = Val(txtDrawB3.Text) + 1
Case "24"
LbNxSt24.Text = Val(LbNxSt24.Text) + 1
txtS30.Text = Val(txtS30.Text) + 4
txtDrawB3.Text = Val(txtDrawB3.Text) + 1
Case "25"
LbNxSt25.Text = Val(LbNxSt25.Text) + 1
txtS30.Text = Val(txtS30.Text) + 5
txtDrawB3.Text = Val(txtDrawB3.Text) + 1
Case "26"
LbNxSt26.Text = Val(LbNxSt26.Text) + 1
txtS30.Text = Val(txtS30.Text) + 6
txtDrawB3.Text = Val(txtDrawB3.Text) + 1
Case "27"
LbNxSt27.Text = Val(LbNxSt27.Text) + 1
txtS30.Text = Val(txtS30.Text) + 7
txtDrawB3.Text = Val(txtDrawB3.Text) + 1
Case "28"
LbNxSt28.Text = Val(LbNxSt28.Text) + 1
txtS30.Text = Val(txtS30.Text) + 8
txtDrawB3.Text = Val(txtDrawB3.Text) + 1
Case "29"
LbNxSt29.Text = Val(LbNxSt29.Text) + 1
txtS30.Text = Val(txtS30.Text) + 9
txtDrawB3.Text = Val(txtDrawB3.Text) + 1
Case "30"
LbNxSt30.Text = Val(LbNxSt30.Text) + 1
txtS30.Text = Val(txtS30.Text) + 10
txtDrawB3.Text = Val(txtDrawB3.Text) + 1
Case "31"
LbNxSt31.Text = Val(LbNxSt31.Text) + 1
txtS40.Text = Val(txtS40.Text) + 1
txtDrawB4.Text = Val(txtDrawB4.Text) + 1
Case "32"
LbNxSt32.Text = Val(LbNxSt32.Text) + 1
txtS40.Text = Val(txtS40.Text) + 2
txtDrawB4.Text = Val(txtDrawB4.Text) + 1
Case "33"
LbNxSt33.Text = Val(LbNxSt33.Text) + 1
txtS40.Text = Val(txtS40.Text) + 3
txtDrawB4.Text = Val(txtDrawB4.Text) + 1
Case "34"
LbNxSt34.Text = Val(LbNxSt34.Text) + 1
txtS40.Text = Val(txtS40.Text) + 4
txtDrawB4.Text = Val(txtDrawB4.Text) + 1
Case "35"
LbNxSt35.Text = Val(LbNxSt35.Text) + 1
txtS40.Text = Val(txtS40.Text) + 5
txtDrawB4.Text = Val(txtDrawB4.Text) + 1
Case "36"
LbNxSt36.Text = Val(LbNxSt36.Text) + 1
txtS40.Text = Val(txtS40.Text) + 6
txtDrawB4.Text = Val(txtDrawB4.Text) + 1
Case "37"
LbNxSt37.Text = Val(LbNxSt37.Text) + 1
txtS40.Text = Val(txtS40.Text) + 7
txtDrawB4.Text = Val(txtDrawB4.Text) + 1
Case "38"
LbNxSt38.Text = Val(LbNxSt38.Text) + 1
txtS40.Text = Val(txtS40.Text) + 8
txtDrawB4.Text = Val(txtDrawB4.Text) + 1
Case "39"
LbNxSt39.Text = Val(LbNxSt39.Text) + 1
txtS40.Text = Val(txtS40.Text) + 9
txtDrawB4.Text = Val(txtDrawB4.Text) + 1
Case "40"
LbNxSt40.Text = Val(LbNxSt40.Text) + 1
txtS40.Text = Val(txtS40.Text) + 10
txtDrawB4.Text = Val(txtDrawB4.Text) + 1
Case "41"
LbNxSt41.Text = Val(LbNxSt41.Text) + 1
txtS50.Text = Val(txtS50.Text) + 1
txtDrawB5.Text = Val(txtDrawB5.Text) + 1
Case "42"
LbNxSt42.Text = Val(LbNxSt42.Text) + 1
txtS50.Text = Val(txtS50.Text) + 2
txtDrawB5.Text = Val(txtDrawB5.Text) + 1
Case "43"
LbNxSt43.Text = Val(LbNxSt43.Text) + 1
txtS50.Text = Val(txtS50.Text) + 3
txtDrawB5.Text = Val(txtDrawB5.Text) + 1
Case "44"
LbNxSt44.Text = Val(LbNxSt44.Text) + 1
txtS50.Text = Val(txtS50.Text) + 4
txtDrawB5.Text = Val(txtDrawB5.Text) + 1
Case "45"
LbNxSt45.Text = Val(LbNxSt45.Text) + 1
txtS50.Text = Val(txtS50.Text) + 5
txtDrawB5.Text = Val(txtDrawB5.Text) + 1
Case "46"
LbNxSt46.Text = Val(LbNxSt46.Text) + 1
txtS50.Text = Val(txtS50.Text) + 6
txtDrawB5.Text = Val(txtDrawB5.Text) + 1
Case "47"
LbNxSt47.Text = Val(LbNxSt47.Text) + 1
txtS50.Text = Val(txtS50.Text) + 7
txtDrawB5.Text = Val(txtDrawB5.Text) + 1
Case "48"
LbNxSt48.Text = Val(LbNxSt48.Text) + 1
txtS50.Text = Val(txtS50.Text) + 8
txtDrawB5.Text = Val(txtDrawB5.Text) + 1
Case "49"
LbNxSt49.Text = Val(LbNxSt49.Text) + 1
txtS50.Text = Val(txtS50.Text) + 9
txtDrawB5.Text = Val(txtDrawB5.Text) + 1
Case "50"
LbNxSt50.Text = Val(LbNxSt50.Text) + 1
txtS50.Text = Val(txtS50.Text) + 10
txtDrawB5.Text = Val(txtDrawB5.Text) + 1
If you can work out the relationship between the "number" and the control, you can get the control like this:
For ary = 1 To 30
Dim aryText = Me.Controls("TextNSt" & ary).Text.Split({","c})
For i = 0 To aryText.Length - 1
Dim s = aryText(i)
Dim n = CInt(s)
Dim LbNxStNum = n Mod 10
If LbNxStNum = 0 Then LbNxStNum = 10
Dim LbNxSt = Me.Controls("LbNxSt" & LbNxStNum)
LbNxSt.Text = (CInt(LbNxSt.Text) + 1).ToString()
Dim txtSNum = (Math.Floor(n / 10) + 1) * 10
Dim txtS = Me.Controls("txtS" & txtSNum)
txtS.Text = (CInt(txtS.Text) + LbNxStNum).ToString()
Dim txtDrawBNum = Math.Ceiling(n / 10)
Dim txtDrawB = Me.Controls("txtDrawB" & txtDrawBNum)
txtDrawB.Text = (CInt(txtDrawB.Text) + 1).ToString()
Next
Next
I may have off-by-one errors in there, so you may need to make adjustments.
If Me is not the container, change it to use the appropriate Panel/whatever container.

How to Store each value of i in cells when i is a decimal?

How do I store each value of i through the loop in cells when i is decimal?
t=0.4
n=0.05 (user input)
For i = 0 To t Step n
Ab = 1042 * i ^ 4 + 1020 * i ^ 3 - 345.63 * i ^ 3 + 52.99 * i
Debug.Print i
Next
Do you mean sth like this
t = 0.4
n = 0.05 '(user input)
j = 1
For i = 0 To t Step n
Ab = 1042 * i ^ 4 + 1020 * i ^ 3 - 345.63 * i ^ 3 + 52.99 * i
Debug.Print i
Cells(j, 1).Value2 = i
Cells(j, 2).Value2 = ab
j = j + 1
Next

Can't figure out do-while and do-until loops

I'm having trouble with the same task that I have to do in four different ways (the four do loops, basically), and it is to generate random numbers and sort them to even and odd. I have specific instructions that this has to be done using do while and do until loops, and so far I've managed to do only one of the four.
The first problem is in the fact that the loop here won't run because nch = ch already and it checks the condition first. Is there a way to get around this? The exit conditions are no more than 290 iterations or nch = ch.
Cells.Clear
Randomize
ch = 0
nch = 0
Worksheets("sheet2").Cells(1, 1) = "Do..Until Loop"
Worksheets("sheet2").Cells(1, 2) = "Even"
Worksheets("sheet2").Cells(1, 3) = "Odd"
Do Until (nch + ch) = 290 Or nch = ch
n = Fix((31 - 13 + 1) * Rnd) + 13
If n Mod 2 = 0 Then
ch = ch + 1
Worksheets("sheet2").Cells(1 + ch, 2) = n
Else
nch = nch + 1
Worksheets("sheet2").Cells(1 + nch, 3) = n
End If
Loop
The second problem is with a do while loop, where I have to achieve the same goal, but the first condition keeps being ignored for some reason.
Do
If n Mod 2 = 0 Then
ch = ch + 1
Worksheets("sheet2").Cells(1 + ch, 2) = n
Else
nch = nch + 1
Worksheets("sheet2").Cells(1 + nch, 3) = n
End If
Loop While (nch + ch) < 290 Or nch <> ch
Any help would be much appreciated! Thanks!
Not sure if you have to write it as 'Loop While' for your home work.
but you could change your syntax to.
Do While (nch + ch) < 290
n = Fix((31 - 13 + 1) * Rnd) + 13
If n Mod 2 = 0 Then
ch = ch + 1
Worksheets("sheet2").Cells(1 + ch, 2) = n
Else
nch = nch + 1
Worksheets("sheet2").Cells(1 + nch, 3) = n
End If
Loop
And your I'm not sure your 'Do Until' needs the second check, try this:
Cells.Clear
Randomize
ch = 0
nch = 0
Worksheets("sheet2").Cells(1, 1) = "Do..Until Loop"
Worksheets("sheet2").Cells(1, 2) = "Even"
Worksheets("sheet2").Cells(1, 3) = "Odd"
Cells.Clear
Randomize
ch = 0
nch = 0
Worksheets("sheet2").Cells(1, 1) = "Do..Until Loop"
Worksheets("sheet2").Cells(1, 2) = "Even"
Worksheets("sheet2").Cells(1, 3) = "Odd"
Do Until (nch + ch) = 290
n = Fix((31 - 13 + 1) * Rnd) + 13
If n Mod 2 = 0 Then
ch = ch + 1
Worksheets("sheet2").Cells(1 + ch, 2) = n
Else
nch = nch + 1
Worksheets("sheet2").Cells(1 + nch, 3) = n
End If
Loop
Also its not the cleanest way but to check a criteria later on you can use this to exit the loop.
If ch = nch Then
Exit Do
End If
If you add a boolean to evaluate it
Cells.Clear
Randomize
ch = 0
nch = 0
equal = false
Worksheets("sheet2").Cells(1, 1) = "Do..Until Loop"
Worksheets("sheet2").Cells(1, 2) = "Even"
Worksheets("sheet2").Cells(1, 3) = "Odd"
Do Until (nch + ch) = 290 Or equal
n = Fix((31 - 13 + 1) * Rnd) + 13
If n Mod 2 = 0 Then
ch = ch + 1
Worksheets("sheet2").Cells(1 + ch, 2) = n
Else
nch = nch + 1
Worksheets("sheet2").Cells(1 + nch, 3) = n
End If
If nch = ch Then
equal = true
End If
Loop
With the second example where is n defined? if n=0 the n Mod 2 will equal 0
"until" stops if true, "while" stops when false.
not ( (nch + ch) = 290 Or nch = ch )
is
(nch + ch) <> 290 AND nch <> ch
the "or" is likely to be your problem.
Please keep in mind the two codes are not totally equivalent, as in the second, the loop is executed at least once.

Why does this VBA-generated QR-Code stutter? (barcode-vba-macro-only)

Context
I am using barcode-vba-macro-only (mentioned in this SO post) in MS Excel 2010 to generate a QR code.
(The bar code will be used to facilitate paying a bill using Girocode, but that is not important here, except to say I need to structure the input exactly the way shown below.)
The problem
The VBA macro creates great QR-Codes, but somehow, when given certain input, the output (encoded in the QR code) "stutters", i.e. repeats part of the text.
E.g., when given this input:
BCD
001
1
SCT
SOLADES1HDB
Recipient First and Last Name
DE86672500200000123456
EUR123.45
it produces this output:
which oddly repeats part of the content:
BCD
001
1
SCT
SOLADES1HDB
Recipient First and Last Name
DE
Recipient First and Last Name
DE86672500200000123456
EUR123.45
(Note the DE and the line Recipient First and Last Name which appear twice.)
What I want
A working, free/GPL solution in Excel to generate such codes ;-) ... for example by understanding why this happens, and fixing the VBA code.
What I have tried (Update 1)
I have played around with different inputs and found that just adding some extra "AAA" to the end of the long number solves the stuttering... so I am intrigued what causes this.
I forked to code on GitHub, added some code comments and translated a few of the existing (Czech) comments
Through some debugging, I found that the implementation messes up the starting position of different encodings (which it stores in array eb): after encoding the "Recipient First and Last Name" including newline and "DE" as "Byte", it probably tries to switch to "Decimal" or "Alphanum" encoding (only 3.33 or 5.5 bit per character instead of 8)... but then falls back to encoding in "Byte" format and thereby gets the starting position wrong.
The code
You can download my test XLSM file here, and access my improved code file on GitHub.
I think the issue is probably in the core function shown below, in the section where the array eb() is filled.
Function qr_gen(ptext As String, poptions As String) As String
Dim encoded1() As Byte ' byte mode (ASCII) all max 3200 bytes
Dim encix1%
Dim ecx_cnt(3) As Integer
Dim ecx_pos(3) As Integer
Dim ecx_poc(3) As Integer
Dim eb(1 To 20, 1 To 4) As Integer 'store how many characters should be in which ECI mode. This is a list of rows, each row corresponding a the next batch of characters with a different ECI mode.
' eb(i, 1) - ECI mode (1 = numeric, 2 = alphanumeric, 3 = byte)
' eb(i, 2) - last character in previous row
' eb(i, 3) - number of characters in THIS row
' eb(i, 4) - number of bits for THIS row
Dim ascimatrix$, mode$, err$
Dim ecl%, r%, c%, mask%, utf8%, ebcnt%
Dim i&, j&, k&, m&
Dim ch%, s%, siz%
Dim x As Boolean
Dim qrarr() As Byte ' final matrix
Dim qrpos As Integer
Dim qrp(15) As Integer ' 1:version,2:size,3:ccs,4:ccb,5:totby,6-12:syncs(7),13-15:versinfo(3)
Dim qrsync1(1 To 8) As Byte
Dim qrsync2(1 To 5) As Byte
ascimatrix = ""
err = ""
mode = "M"
i = InStr(poptions, "mode=")
If i > 0 Then mode = Mid(poptions, i + 5, 1)
' M=0,L=1,H=2,Q=3
ecl = InStr("MLHQ", mode) - 1
If ecl < 0 Then mode = "M": ecl = 0
If ptext = "" Then
err = "Not data"
Exit Function
End If
For i = 1 To 3
ecx_pos(i) = 0
ecx_cnt(i) = 0
ecx_poc(i) = 0
Next i
ebcnt = 1
utf8 = 0
For i = 1 To Len(ptext) + 1
' Decide how many bytes this character has
If i > Len(ptext) Then
k = -5 ' End of text --> skip several code sections
Else ' need to parse character i of ptext and decide how many bytes it has
k = AscL(Mid(ptext, i, 1))
If k >= &H1FFFFF Then ' FFFF - 1FFFFFFF
m = 4
k = -1
ElseIf k >= &H7FF Then ' 7FF-FFFF 3 bytes
m = 3
k = -1
ElseIf k >= 128 Then
m = 2
k = -1
Else ' normal 7bit ASCII character, so it is worth it to check if it belong to the Numeric or Alphanumeric subsets defined in ECI (array qralnum)
m = 1
k = InStr(qralnum, Mid(ptext, i, 1)) - 1
End If
End If
' Depending on k and a lot of other things, increase ebcnt
If (k < 0) Then ' Treat mult-byte case or exit? (bude byte nebo konec)
If ecx_cnt(1) >= 9 Or (k = -5 And ecx_cnt(1) = ecx_cnt(3)) Then ' Until now it was possible numeric??? (Az dosud bylo mozno pouzitelne numeric)
If (ecx_cnt(2) - ecx_cnt(1)) >= 8 Or (ecx_cnt(3) = ecx_cnt(2)) Then ' pred num je i pouzitelny alnum
If (ecx_cnt(3) > ecx_cnt(2)) Then ' Jeste pred alnum bylo byte
eb(ebcnt, 1) = 3 ' Typ byte
eb(ebcnt, 2) = ecx_pos(3) ' Position pozice
eb(ebcnt, 3) = ecx_cnt(3) - ecx_cnt(2) ' delka
ebcnt = ebcnt + 1
ecx_poc(3) = ecx_poc(3) + 1
End If
eb(ebcnt, 1) = 2 ' Typ alnum
eb(ebcnt, 2) = ecx_pos(2)
eb(ebcnt, 3) = ecx_cnt(2) - ecx_cnt(1) ' delka
ebcnt = ebcnt + 1
ecx_poc(2) = ecx_poc(2) + 1
ecx_cnt(2) = 0
ElseIf ecx_cnt(3) > ecx_cnt(1) Then ' byly bytes pred numeric
eb(ebcnt, 1) = 3 ' Typ byte
eb(ebcnt, 2) = ecx_pos(3) ' Position pozice
eb(ebcnt, 3) = ecx_cnt(3) - ecx_cnt(1) ' delka
ebcnt = ebcnt + 1
ecx_poc(3) = ecx_poc(3) + 1
End If
ElseIf (ecx_cnt(2) >= 8) Or (k = -5 And ecx_cnt(2) = ecx_cnt(3)) Then ' Az dosud bylo mozno pouzitelne alnum
If (ecx_cnt(3) > ecx_cnt(2)) Then ' Jeste pred alnum bylo byte
eb(ebcnt, 1) = 3 ' Typ byte
eb(ebcnt, 2) = ecx_pos(3) ' Position pozice
eb(ebcnt, 3) = ecx_cnt(3) - ecx_cnt(2) ' delka
ebcnt = ebcnt + 1
ecx_poc(3) = ecx_poc(3) + 1
End If
eb(ebcnt, 1) = 2 ' Typ alnum
eb(ebcnt, 2) = ecx_pos(2)
eb(ebcnt, 3) = ecx_cnt(2) ' delka
ebcnt = ebcnt + 1
ecx_poc(2) = ecx_poc(2) + 1
ecx_cnt(3) = 0
ecx_cnt(2) = 0 ' vse zpracovano
ElseIf (k = -5 And ecx_cnt(3) > 0) Then ' konec ale mam co ulozit
eb(ebcnt, 1) = 3 ' Typ byte
eb(ebcnt, 2) = ecx_pos(3) ' Position pozice
eb(ebcnt, 3) = ecx_cnt(3) ' delka
ebcnt = ebcnt + 1
ecx_poc(3) = ecx_poc(3) + 1
End If
End If
If k = -5 Then Exit For
If (k >= 0) Then ' We can alphanumeric? (Muzeme alnum)
If (k >= 10 And ecx_cnt(1) >= 12) Then ' Until now it was perhaps numeric (Az dosud bylo mozno num)
If (ecx_cnt(2) - ecx_cnt(1)) >= 8 Or (ecx_cnt(3) = ecx_cnt(2)) Then ' There is also an alphanumeric which is worth it(Je tam i alnum ktery stoji za to)
If (ecx_cnt(3) > ecx_cnt(2)) Then ' Even before it was alnum byte (Jeste pred alnum bylo byte)
eb(ebcnt, 1) = 3 ' Typ byte
eb(ebcnt, 2) = ecx_pos(3) ' Position (pozice)
eb(ebcnt, 3) = ecx_cnt(3) - ecx_cnt(2) ' length (delka)
ebcnt = ebcnt + 1
ecx_poc(3) = ecx_poc(3) + 1
End If
eb(ebcnt, 1) = 2 ' Typ alnum
eb(ebcnt, 2) = ecx_pos(2)
eb(ebcnt, 3) = ecx_cnt(2) - ecx_cnt(1) ' length (delka)
ebcnt = ebcnt + 1
ecx_poc(2) = ecx_poc(2) + 1
ecx_cnt(2) = 0 ' processed everything (vse zpracovano)
ElseIf (ecx_cnt(3) > ecx_cnt(1)) Then ' Previous Num is byte (Pred Num je byte)
eb(ebcnt, 1) = 3 ' Typ byte
eb(ebcnt, 2) = ecx_pos(3) ' Position (pozice)
eb(ebcnt, 3) = ecx_cnt(3) - ecx_cnt(1) ' length (delka)
ebcnt = ebcnt + 1
ecx_poc(3) = ecx_poc(3) + 1
End If
eb(ebcnt, 1) = 1 ' Typ numerix
eb(ebcnt, 2) = ecx_pos(1)
eb(ebcnt, 3) = ecx_cnt(1) ' length (delka)
ebcnt = ebcnt + 1
ecx_poc(1) = ecx_poc(1) + 1
ecx_cnt(1) = 0
ecx_cnt(2) = 0
ecx_cnt(3) = 0 ' processed everything (vse zpracovano)
End If
If ecx_cnt(2) = 0 Then ecx_pos(2) = i
ecx_cnt(2) = ecx_cnt(2) + 1
Else ' possible alnum (mozno alnum)
ecx_cnt(2) = 0
End If
If k >= 0 And k < 10 Then ' Can be numeric (muze byt numeric)
If ecx_cnt(1) = 0 Then ecx_pos(1) = i
ecx_cnt(1) = ecx_cnt(1) + 1
Else
ecx_cnt(1) = 0
End If
If ecx_cnt(3) = 0 Then ecx_pos(3) = i
ecx_cnt(3) = ecx_cnt(3) + m
utf8 = utf8 + m
If ebcnt >= 16 Then ' We have already taken 3 other blocks of bits (Uz by se mi tri dalsi bloky stejne nevesli)
ecx_cnt(1) = 0
ecx_cnt(2) = 0
End If
Debug.Print "Character:'" & Mid(ptext, i, 1) & "'(" & k & _
") ebn=" & ecx_pos(1) & "." & ecx_cnt(1) & _
" eba=" & ecx_pos(2) & "." & ecx_cnt(2) & _
" ebb=" & ecx_pos(3) & "." & ecx_cnt(3)
Next
ebcnt = ebcnt - 1 ' ebcnt now has its final value
Debug.Print ("ebcnt=" & ebcnt)
c = 0
For i = 1 To ebcnt
Select Case eb(i, 1)
Case 1: eb(i, 4) = Int(eb(i, 3) / 3) * 10 + (eb(i, 3) Mod 3) * 3 + IIf((eb(i, 3) Mod 3) > 0, 1, 0)
Case 2: eb(i, 4) = Int(eb(i, 3) / 2) * 11 + (eb(i, 3) Mod 2) * 6
Case 3: eb(i, 4) = eb(i, 3) * 8
End Select
c = c + eb(i, 4)
Next i
Debug.Print ("c=" & c)
' UTF-8 is default not need ECI value - zxing cannot recognize
' Call qr_params(i * 8 + utf8,mode,qrp)
Call qr_params(c, ecl, qrp, ecx_poc)
If qrp(1) <= 0 Then
err = "Too long"
Exit Function
End If
siz = qrp(2)
Debug.Print "ver:" & qrp(1) & mode & " size " & siz & " ecc:" & qrp(3) & "x" & qrp(4) & " d:" & (qrp(5) - qrp(3) * qrp(4))
'MsgBox "ver:" & qrp(1) & mode & " size " & siz & " ecc:" & qrp(3) & "x" & qrp(4) & " d:" & (qrp(5) - qrp(3) * qrp(4))
ReDim encoded1(qrp(5) + 2)
' Table 3 — Number of bits in character count indicator for QR Code 2005:
' mode indicator (1=num,2=AlNum,4=Byte,8=kanji,ECI=7)
' mode: Byte Alphanum Numeric Kanji
' ver 1..9 : 8 9 10 8
' 10..26 : 16 11 12 10
' 27..40 : 16 13 14 12
' UTF-8 is default not need ECI value - zxing cannot recognize
' if utf8 > 0 Then
' k = &H700 + 26 ' UTF-8=26 ; Win1250 = 21; 8859-2 = 4 viz http://strokescribe.com/en/ECI.html
' bb_putbits(encoded1,encix1,k,12)
' End If
encix1 = 0
For i = 1 To ebcnt
Select Case eb(i, 1)
Case 1: c = IIf(qrp(1) < 10, 10, IIf(qrp(1) < 27, 12, 14)): k = 2 ^ c + eb(i, 3) ' encoding mode "Numeric"
Case 2: c = IIf(qrp(1) < 10, 9, IIf(qrp(1) < 27, 11, 13)): k = 2 * (2 ^ c) + eb(i, 3) ' encoding mode "alphanum
Case 3: c = IIf(qrp(1) < 10, 8, 16): k = 4 * (2 ^ c) + eb(i, 3) ' encoding mode "Byte"
End Select
Call bb_putbits(encoded1, encix1, k, c + 4)
Debug.Print "ver:" & qrp(1) & mode & " size " & siz & " ecc:" & qrp(3) & "x" & qrp(4) & " d:" & (qrp(5) - qrp(3) * qrp(4))
j = 0 ' count characters that have been output in THIS row eb(i,...)
m = eb(i, 2) 'Start (after) last character of input from previous row
r = 0
While j < eb(i, 3)
k = AscL(Mid(ptext, m, 1))
m = m + 1
If eb(i, 1) = 1 Then
' parse numeric input - output 3 decimal digits into 10 bit
r = (r * 10) + ((k - &H30) Mod 10)
If (j Mod 3) = 2 Then
Call bb_putbits(encoded1, encix1, r, 10)
r = 0
End If
j = j + 1
ElseIf eb(i, 1) = 2 Then
' parse alphanumeric input - output 2 alphanumeric characters into 11 bit
r = (r * 45) + ((InStr(qralnum, Chr(k)) - 1) Mod 45)
If (j Mod 2) = 1 Then
Call bb_putbits(encoded1, encix1, r, 11)
r = 0
End If
j = j + 1
Else
' Okay, byte mode: coding according to Chapter "6.4.2 Extended Channel Interpretation (ECI) mode" of ISOIEC 18004_2006Cor 1_2009.pdf
If k > &H1FFFFF Then ' FFFF - 1FFFFFFF
ch = &HF0 + Int(k / &H40000) Mod 8
Call bb_putbits(encoded1, encix1, ch, 8)
ch = 128 + Int(k / &H1000) Mod 64
Call bb_putbits(encoded1, encix1, ch, 8)
ch = 128 + Int(k / 64) Mod 64
Call bb_putbits(encoded1, encix1, ch, 8)
ch = 128 + k Mod 64
Call bb_putbits(encoded1, encix1, ch, 8)
j = j + 4
ElseIf k > &H7FF Then ' 7FF-FFFF 3 bytes
ch = &HE0 + Int(k / &H1000) Mod 16
Call bb_putbits(encoded1, encix1, ch, 8)
ch = 128 + Int(k / 64) Mod 64
Call bb_putbits(encoded1, encix1, ch, 8)
ch = 128 + k Mod 64
Call bb_putbits(encoded1, encix1, ch, 8)
j = j + 3
ElseIf k > &H7F Then ' 2 bytes
ch = &HC0 + Int(k / 64) Mod 32
Call bb_putbits(encoded1, encix1, ch, 8)
ch = 128 + k Mod 64
Call bb_putbits(encoded1, encix1, ch, 8)
j = j + 2
Else
ch = k Mod 256
Call bb_putbits(encoded1, encix1, ch, 8)
j = j + 1
End If
End If
Wend
Select Case eb(i, 1)
Case 1:
If (j Mod 3) = 1 Then
Call bb_putbits(encoded1, encix1, r, 4)
ElseIf (j Mod 3) = 2 Then
Call bb_putbits(encoded1, encix1, r, 7)
End If
Case 2:
If (j Mod 2) = 1 Then Call bb_putbits(encoded1, encix1, r, 6)
End Select
'MsgBox "blk[" & i & "] t:" & eb(i,1) & "from " & eb(i,2) & " to " & eb(i,3) + eb(i,2) & " bits=" & encix1
Next i
Call bb_putbits(encoded1, encix1, 0, 4) ' end of chain
If (encix1 Mod 8) <> 0 Then ' round to byte
Call bb_putbits(encoded1, encix1, 0, 8 - (encix1 Mod 8))
End If
' padding
i = (qrp(5) - qrp(3) * qrp(4)) * 8
If encix1 > i Then
err = "Encode length error"
Exit Function
End If
' padding 0xEC,0x11,0xEC,0x11...
Do While encix1 < i
Call bb_putbits(encoded1, encix1, &HEC11, 16)
Loop
' doplnime ECC
i = qrp(3) * qrp(4) 'ppoly, pmemptr , psize , plen , pblocks
Call qr_rs(&H11D, encoded1, qrp(5) - i, i, qrp(4))
'Call arr2hexstr(encoded1)
encix1 = qrp(5)
' Pole pro vystup
ReDim qrarr(0)
ReDim qrarr(1, qrp(2) * 24& + 24&) ' 24 bytes per row
qrarr(0, 0) = 0
ch = 0
Call bb_putbits(qrsync1, ch, Array(&HFE, &H82, &HBA, &HBA, &HBA, &H82, &HFE, 0), 64)
Call qr_mask(qrarr, qrsync1, 8, 0, 0) ' sync UL
Call qr_mask(qrarr, 0, 8, 8, 0) ' fmtinfo UL under - bity 14..9 SYNC 8
Call qr_mask(qrarr, qrsync1, 8, 0, siz - 7) ' sync UR ( o bit vlevo )
Call qr_mask(qrarr, 0, 8, 8, siz - 8) ' fmtinfo UR - bity 7..0
Call qr_mask(qrarr, qrsync1, 8, siz - 7, 0) ' sync DL (zasahuje i do quiet zony)
Call qr_mask(qrarr, 0, 8, siz - 8, 0) ' blank nad DL
For i = 0 To 6
x = qr_bit(qrarr, -1, i, 8, 0) ' svisle fmtinfo UL - bity 0..5 SYNC 6,7
x = qr_bit(qrarr, -1, i, siz - 8, 0) ' svisly blank pred UR
x = qr_bit(qrarr, -1, siz - 1 - i, 8, 0) ' svisle fmtinfo DL - bity 14..8
Next
x = qr_bit(qrarr, -1, 7, 8, 0) ' svisle fmtinfo UL - bity 0..5 SYNC 6,7
x = qr_bit(qrarr, -1, 7, siz - 8, 0) ' svisly blank pred UR
x = qr_bit(qrarr, -1, 8, 8, 0) ' svisle fmtinfo UL - bity 0..5 SYNC 6,7
x = qr_bit(qrarr, -1, siz - 8, 8, 1) ' black dot DL
If qrp(13) <> 0 Or qrp(14) <> 0 Then ' versioninfo
' UR ver 0 1 2;3 4 5;...;15 16 17
' LL ver 0 3 6 9 12 15;1 4 7 10 13 16; 2 5 8 11 14 17
k = 65536 * qrp(13) + 256& * qrp(14) + 1& * qrp(15)
c = 0: r = 0
For i = 0 To 17
ch = k Mod 2
x = qr_bit(qrarr, -1, r, siz - 11 + c, ch) ' UR ver
x = qr_bit(qrarr, -1, siz - 11 + c, r, ch) ' DL ver
c = c + 1
If c > 2 Then c = 0: r = r + 1
k = Int(k / 2&)
Next
End If
c = 1
For i = 8 To siz - 9 ' sync lines
x = qr_bit(qrarr, -1, i, 6, c) ' vertical on column 6
x = qr_bit(qrarr, -1, 6, i, c) ' horizontal on row 6
c = (c + 1) Mod 2
Next
' other syncs
ch = 0
Call bb_putbits(qrsync2, ch, Array(&H1F, &H11, &H15, &H11, &H1F), 40)
ch = 6
Do While ch > 0 And qrp(6 + ch) = 0
ch = ch - 1
Loop
If ch > 0 Then
For c = 0 To ch
For r = 0 To ch
' corners
If (c <> 0 Or r <> 0) And _
(c <> ch Or r <> 0) And _
(c <> 0 Or r <> ch) Then
Call qr_mask(qrarr, qrsync2, 5, qrp(r + 6) - 2, qrp(c + 6) - 2)
End If
Next r
Next c
End If
' qr_fill(parr as Variant, psiz%, pb as Variant, pblocks%, pdlen%, ptlen%)
' vyplni pole parr (psiz x 24 bytes) z pole pb pdlen = pocet dbytes, pblocks = bloku, ptlen celkem
Call qr_fill(qrarr, siz, encoded1, qrp(4), qrp(5) - qrp(3) * qrp(4), qrp(5))
mask = 8 ' auto
i = InStr(poptions, "mask=")
If i > 0 Then mask = val(Mid(poptions, i + 5, 1))
If mask < 0 Or mask > 7 Then
j = -1
For mask = 0 To 7
GoSub addmm
i = qr_xormask(qrarr, siz, mask, False)
' MsgBox "score mask " & mask & " is " & i
If i < j Or j = -1 Then j = i: s = mask
Next mask
mask = s
' MsgBox "best is " & mask & " with score " & j
End If
GoSub addmm
i = qr_xormask(qrarr, siz, mask, True)
ascimatrix = ""
For r = 0 To siz Step 2
s = 0
For c = 0 To siz Step 2
If (c Mod 8) = 0 Then
ch = qrarr(1, s + 24 * r)
If r < siz Then i = qrarr(1, s + 24 * (r + 1)) Else i = 0
s = s + 1
End If
ascimatrix = ascimatrix _
& Chr(97 + (ch Mod 4) + 4 * (i Mod 4))
ch = Int(ch / 4)
i = Int(i / 4)
Next
ascimatrix = ascimatrix & vbNewLine
Next r
ReDim qrarr(0)
qr_gen = ascimatrix
Exit Function
addmm:
k = ecl * 8 + mask
' poly: 101 0011 0111
Call qr_bch_calc(k, &H537)
'MsgBox "mask :" & hex(k,3) & " " & hex(k xor &H5412,3)
k = k Xor &H5412 ' micro xor &H4445
r = 0
c = siz - 1
For i = 0 To 14
ch = k Mod 2
k = Int(k / 2)
x = qr_bit(qrarr, -1, r, 8, ch) ' svisle fmtinfo UL - bity 0..5 SYNC 6,7 .... 8..14 dole
x = qr_bit(qrarr, -1, 8, c, ch) ' vodorovne odzadu 0..7 ............ 8,SYNC,9..14
c = c - 1
r = r + 1
If i = 7 Then c = 7: r = siz - 7
If i = 5 Then r = r + 1 ' preskoc sync vodorvny
If i = 8 Then c = c - 1 ' preskoc sync svisly
Next
Return
End Function ' qr_gen
Why this happens
Through some debugging, I found that the original implementation messes up the starting position of different encodings (which it stores in array eb): after encoding the "Recipient First and Last Name" including newline and "DE" as "Byte", it probably tries to switch to "Decimal" or "Alphanum" encoding (only 3.33 or 5.5 bit per character instead of 8)... but then falls back to encoding in "Byte" format and thereby gets the starting position wrong.
The solution
I have now added some error checking to the code which manually removes the stuttering.
You can find my improved code on Github, see in particular barcody.bas.
The key addition is this part:
i = 1
While i < (ebcnt - 1)
If eb(i, 2) + eb(i, 3) <> eb(i + 1, 2) Then
' oops, this should not happen. First document it:
Debug.Print ("eb() rows " & i & " and " & i + 1 & " are overlapping!")
' Now Lets see if we can fix it:
wasfixed = False
For k = i To 1 Step -1
If eb(k, 2) = eb(i + 1, 2) Then
' okay, the row k to i seem to be contained in i+1 and following. Delete k to i ...
For j = k To ebcnt - (i - k + 1) ' ... by copying upwards all later rows...
eb(j, 1) = eb(j + (i - k + 1), 1)
eb(j, 2) = eb(j + (i - k + 1), 2)
eb(j, 3) = eb(j + (i - k + 1), 3)
eb(j, 4) = eb(j + (i - k + 1), 4)
Next j
ebcnt = ebcnt - (i - k + 1) ' and correcting the total rowcount
wasfixed = True
Exit For
End If
Next k
If Not (wasfixed) Then
MsgBox ("The input text analysis failed - entering debug mode...")
Debug.Assert False
End If
End If
i = i + 1
Wend
I have noticed this same issue with certain character being a trigger for this problem when it comes after something. In your case, it looks like something after "DE" Since I didn't write the code I haven't thoroughly search in the code why this would trigger a repeat but I'm guessing that some of the hex conversion in the function causes this problem. In my case, I avoided the issue by having a space in front of the entire string being input to the generator. For some reasons, having the space at the beginning somehow prevent the triggering of the repeat. The reader program that reads the barcode in my case would remove the space from the string anyway so it doesn't matter.
I don't know whether it's a problem for your application, but try putting a blank space (" ") in front of the problematic string (DE86672500200000123456 )and see whether that works.
BCD
001
1
SCT
SOLADES1HDB
Recipient First and Last Name
DE86672500200000123456
EUR123.45

Excel VBA - Run-time error 1004

When I run the code below I get the annoying 1004 error.
Sub TEST_MACRO()
Dim shSource As Worksheet
Dim shDest As Worksheet
Dim DateRange As Range
Dim i As Integer, nullcounter As Integer, nullcounterov As Integer, tablelength As Integer, tablelengthov As Integer, DateRangeSize As Integer
Dim q As Integer
Set shSource = ThisWorkbook.Sheets("Sheet1")
Set shDest = ThisWorkbook.Sheets("Sheet2")
Set DateRange = shSource.Application.InputBox("Select date", Type:=8)
DateRangeSize = DateRange.Rows.Count
nullcounter = 0
nullcounterov = 0
tablelength = 3
tablelengthov = 3
For q = 0 To DateRangeSize - 1
shDest.Range("C4:I17").ClearContents
'THIS IS THE CODE FOR ABC
For i = 0 To 3
If IsEmpty(shSource.Cells(DateRange.Row + q, 2 + i)) = True Or shSource.Cells(DateRange.Row + q, 2 + i) = 0 Then
nullcounter = nullcounter + 1
Else
shDest.Cells(4 + i - nullcounter, 4) = shSource.Cells(DateRange.Row + q, 2 + i)
shDest.Cells(4 + i - nullcounter, 5) = shSource.Cells(DateRange.Row + q, 6 + i)
shDest.Cells(4 + i - nullcounter, 3) = shSource.Cells(1, 2 + i)
tablelength = tablelength + 1
End If
Next
'THIS IS THE CODE FOR XYZ
For i = 0 To 6
If IsEmpty(shSource.Cells(DateRange.Row + q, 10 + i)) = True Or shSource.Cells(DateRange.Row + q, 10 + i) = 0 Then
nullcounterov = nullcounterov + 1
Else
shDest.Cells(4 + i - nullcounterov, 8) = shSource.Cells(DateRange.Row + q, 10 + i)
shDest.Cells(4 + i - nullcounterov, 9) = shSource.Cells(DateRange.Row + q, 17 + i)
shDest.Cells(4 + i - nullcounterov, 7) = shSource.Cells(1, 10 + i)
tablelengthov = tablelengthov + 1
End If
Next
Next
End Sub
The excel sheet I run this on looks like this:
http://i.imgur.com/V7tWTKq.png
The code works for ABC but it doesn't for XYZ. I'm guessing the 0 value cells are messing it up but I don't understand why.
The goal of the code is:
User is prompted to select a range of size DateRangeSize.
For each row in the range the code copies the values of ABC, ABC-D, XYZ and XYZ-D if they aren't 0 and writes them to sheet 2.
If the number of rows in the range is 1, the code works fine. But if the number of rows is greater than 1, I get the 1004 error where this part of the code is highlight:
shDest.Cells(4 + i - nullcounterov, 8) = shSource.Cells(DateRange.Row + q, 10 + i)
I appreciate the help.
EDIT: I just want to add that the code ALWAYS works for ABC. If the number of rows is 2 then the ABC values for the second row are printed in sheet2 but the code breaks when it attempts to do the same for XYZ.
EDIT 2: I added 0 values to the ABC portion but the code still works for ABC! This is so frustrating.
I figured it out. I defined
nullcounter = 0
nullcounterov = 0
tablelength = 3
tablelengthov = 3
Outside of the loop so they kept on increasing.
shDest.Cells(4 + i - nullcounterov, 8) = shSource.Cells(DateRange.Row + q, 10 + i)
Eventually 4 + i << nullcounterov and excel tried to write to a cell that didn't exist.
The fixed code:
Sub TEST_MACRO()
Dim shSource As Worksheet
Dim shDest As Worksheet
Dim DateRange As Range
Dim i As Integer, nullcounter As Integer, nullcounterov As Integer, tablelength As Integer, tablelengthov As Integer, DateRangeSize As Integer
Dim q As Integer
Set shSource = ThisWorkbook.Sheets("Sheet1")
Set shDest = ThisWorkbook.Sheets("Sheet2")
Set DateRange = shSource.Application.InputBox("Select date", Type:=8)
DateRangeSize = DateRange.Rows.Count
For q = 0 To DateRangeSize - 1
nullcounter = 0
nullcounterov = 0
tablelength = 3
tablelengthov = 3
shDest.Range("C4:I17").ClearContents
'THIS IS THE CODE FOR ABC
For i = 0 To 3
If IsEmpty(shSource.Cells(DateRange.Row + q, 2 + i)) = True Or shSource.Cells(DateRange.Row + q, 2 + i) = 0 Then
nullcounter = nullcounter + 1
Else
shDest.Cells(4 + i - nullcounter, 4) = shSource.Cells(DateRange.Row + q, 2 + i)
shDest.Cells(4 + i - nullcounter, 5) = shSource.Cells(DateRange.Row + q, 6 + i)
shDest.Cells(4 + i - nullcounter, 3) = shSource.Cells(1, 2 + i)
tablelength = tablelength + 1
End If
Next
'THIS IS THE CODE FOR XYZ
For i = 0 To 6
If IsEmpty(shSource.Cells(DateRange.Row + q, 10 + i)) = True Or shSource.Cells(DateRange.Row + q, 10 + i) = 0 Then
nullcounterov = nullcounterov + 1
Else
shDest.Cells(4 + i - nullcounterov, 8) = shSource.Cells(DateRange.Row + q, 10 + i)
shDest.Cells(4 + i - nullcounterov, 9) = shSource.Cells(DateRange.Row + q, 17 + i)
shDest.Cells(4 + i - nullcounterov, 7) = shSource.Cells(1, 10 + i)
tablelengthov = tablelengthov + 1
End If
Next
Next
End Sub