Help with For Loop - works great except for the last bit

Oberon70

Board Regular
Joined
Jan 21, 2022
Messages
160
Office Version
  1. 365
Platform
  1. Windows
Hi,

I have a loop that moves the data into different format, so I can paste it into a system.

The loop is working great until the end.

section 1 of the loop has 16 items on one page.
Section 2 has 2 lots of 6 and last page 4.

So lets say I have 155 transactions that equates to set of 9 complete sets of 16 and the last set being 11
The same if I have 70 transactions that equates to to 4 complete sets of 16 and the last set being 6.

The 1st part of my code I was able to get the loop to recognise that the last section needs to be the remaining number from the transaction. Basically, I subtracted 16 from the transaction until the count was created than the transaction then I over rode the final loop on section one to equal the number of transactions left, but I can't seem to figure how to do this on the 2nd part.

I really hope someone can help me on this. so lets say the below was 27 transactions, 1st section of the code reduce the last section to 11, but the 2nd part still is completing the all three loops, were it need to only do two loops and one less entry. sorry, hope this make since.

1648781930315.png



VBA Code:
Sub CrtWorkFlw()

Dim lastrow As Double
Dim AgtName As String
Dim InvNum As String
Dim TransCnt As Double 'The total count of transactions being looped.
Dim Mloop As Double 'The start of the main loop through the transactions
Dim Tloop As Double 'The start of the loop for recovered funds
Dim rNum As Double 'this is for the row Location for data to be entered on the spreadsheet cells(rNum, cNum)
Dim cNum As Double 'this is for the column Location for data to be entered on the spreadsheet cells(rNum, cNum)
Dim clcnt2 As Double 'variable to assist with the location of the data being sorted.
Dim clcnt As Double
Dim nLoop As Double 'How many loops through the code that the main loop will do.
Dim TloopCnt As Double  'what the recvovred funds are counting down too.
Dim cc As Double 'variable used to asssit with keeping track if there is less than 16 entries left to loop through.
Dim dd As Double



Dim CommLoop As Double
Dim CommLoop2 As Double
Dim CommLoop3 As Double


Dim CommLoopCnt As Double
Dim CommLoopCnt2 As Double


lastrow = wsSupSheet.Cells(Rows.Count, "A").End(xlUp).Row

AgtName = Trim(wsInvDtls.Range("B3").Value)
InvNum = wsInvDtls.Range("B1").Value

Select Case AgtName
    Case "RecoveriesCorp"
        AgtName = "RecovCrp"
    Case "National Mercantile"
        AgtName = "National Merc"
End Select

wsSupSheet.Range("A" & lastrow & ":" & "C" & lastrow).Offset(1).Merge
wsSupSheet.Range("A" & lastrow & ":" & "C" & lastrow).Offset(1) = (AgtName & " " & InvNum)

TransCnt = wsTmpSh.Cells(Rows.Count, "A").End(xlUp).Row - 1 'Taken one off for the header.

rNum = 3
cNum = 2
clcnt = 1
clcnt2 = 1
nLoop = TransCnt / 16
TloopCnt = 16
cc = TransCnt
dd = TransCnt + 16
CommLoopCnt = 3
CommLoopCnt2 = 6

'''''''''''''''''''''''Main Loop'''''''''''''''''''''''

For Mloop = 1 To nLoop + 1
    
'''''''''''''''''''''''T Screen Loop'''''''''''''''''''

        For Tloop = 1 To TloopCnt
            wsSupSheet.Range("A" & lastrow).Offset(rNum, cNum) = "K" & wsTmpSh.Range("A" & clcnt + 1)
            wsSupSheet.Range("A" & lastrow).Offset(rNum, cNum + 1) = wsTmpSh.Range("B" & clcnt + 1)
            rNum = rNum + 1
         
            clcnt = clcnt + 1
        Next Tloop
        cc = cc - 16
        
        If TloopCnt > cc Then
            TloopCnt = cc
            
        End If
        
'''''''''''''''''''''''Commision Loop'''''''''''''''''''
        dd = cc
        rNum = rNum + 1
        'dd = dd - 16
        Debug.Print cc
        
        
        CommLoopCnt2 = 6
        
        
        For CommLoop = 1 To CommLoopCnt
            For CommLoop2 = 1 To CommLoopCnt2
                wsSupSheet.Range("A" & lastrow).Offset(rNum, cNum) = "N" & wsTmpSh.Range("A" & clcnt2 + 1)
                clcnt2 = clcnt2 + 1
                cNum = cNum + 1
              
            Next CommLoop2
                  'dd = dd - 2
                If CommLoop = 2 Then
                  CommLoopCnt2 = 4
                End If
                cNum = 2
                rNum = rNum + 1
               ' If cc < 16 Then
                   ' CommLoopCnt2 = CommLoopCnt2 + cc
               ' End If
           
       Next CommLoop
        
        
        rNum = rNum + 1
  
Next Mloop

End Sub
 

Excel Facts

Which lookup functions find a value equal or greater than the lookup value?
MATCH uses -1 to find larger value (lookup table must be sorted ZA). XLOOKUP uses 1 to find values greater and does not need to be sorted.
use a double loop and exit for
VBA Code:
Sub DoubleLoop()
     'So lets say I have 155 transactions that equates to set of 9 complete sets of 16 and the last set being 11
     'The same if I have 70 transactions that equates to to 4 complete sets of 16 and the last set being 6.
     Dim i0, i, i1, s, iSet, iTotal

     For i0 = 0 To 1                                            'do the double loop twice, 1st time for 155 items, 2nd time for 70
          If i0 = 0 Then
               iSet = 16
               iTotal = 155
          Else
               iSet = 16
               iTotal = 70
          End If

          s = ""                                                'start empty
          For i = 1 To iTotal Step iSet                         'outer loop for the sets of 16
               For i1 = i To i + iSet - 1                       'inner loop (until 16 in case of a complete set)
                    s = s & "," & i1                            'do your thing (here i only added something to a string
                    If i1 >= iTotal Then Exit For               'in case of an incomplete serie of 16
               Next
               s = s & vbLf & IIf(i1 >= iTotal, "done", "")     'after a complete set of 16, do something, here i added a linefeed and in case of last loop "done"
          Next

          MsgBox s, , "itotal = " & iTotal & "   iset = " & iSet     'result of the double loop
     Next
End Sub
 
Upvote 0
but the 2nd part still is completing the all three loops, were it need to only do two loops
I think everything can be done with a single loop.

I don't quite understand this part of your macro:
wsSupSheet.Range("A" & lastrow). Offset(rNum, cNum).
But if the data starts to be written in A2, with the following you can do it:

VBA Code:
Sub CrtWorkFlw_2()
  Dim i As Long, j As Long, lr As Long, lr2 As Long, m1 As Long, m2 As Long, n As Long, x As Long

  lr = wsSupSheet.Range("A" & Rows.Count).End(3).Row
  lr2 = wsTmpSh.Range("A" & Rows.Count).End(3).Row
  wsSupSheet.Range("A" & lr).Offset(1).Value = Trim(wsInvDtls.Range("B3").Value) & " " & wsInvDtls.Range("B1").Value
  j = 3
  m1 = lr + 3
  If lr2 - 1 >= 17 Then x = 17 Else x = lr2
  m2 = lr + x + 3
  
  For i = 2 To lr2
    n = n + 1
    If n = 17 Then
      n = 1
      lr2 = lr2 - 16
      If lr2 - 1 >= 17 Then x = 17 - 1 Else x = lr2 - 1
      m1 = m1 + 5
      m2 = m2 + x + 3
      j = 3
    End If
    
    If j = 9 Then
      j = 3
      m2 = m2 + 1
    End If
    wsSupSheet.Cells(m1, 3).Resize(1, 2).Value = Array("K" & wsTmpSh.Range("A" & i), wsTmpSh.Range("B" & i))
    wsSupSheet.Cells(m2, j).Value = "N" & wsTmpSh.Range("A" & i)
    m1 = m1 + 1
    j = j + 1
  Next
End Sub
 
Upvote 0
Thank you again for your help and sorry if my post was confusing. I am going to walk through your code and see how it works as it looks really nice. I actually don't need to run two loops one for 155 or 70. This is for a statement that I am copying the transactions into a specific arrangement on a blank form. I was just advising that the loop needs to be dynamic and I will need to run through three separate steps in sets of 16.

I am on my home computer, so I can use the adding XL2BB, work computer security is strict, so it isn't installed nor RubberDuck.

The below is a shortened version of a list of transactions, this list is very basic, It only includes the Reference number, the payment and the charge

Copy of Super Speed Receipting Test Spreadsheet.xlsm
ABC
1Claim NumberAmountInc Comm
2DP1303148405.5
3KV1969096405.5
4OX133183310013.76
5WD127011519026.14
6YF171851010013.76
7PI128963140055
8LS1778870608.26
9EN1882707608.25
10NA165551020027.5
11ZQ1978656608.26
12IC1308145405.5
13RZ1600817405.5
14AL1777416304.14
15DP1181379608.26
16KX1939472608.26
17OV142102410013.76
18GU1198119405.5
19JR1300591405.5
20KH161512620027.5
21WF1516483202.76
22BE196649512016.5
23MH11011640687.5
24IA1557922253.44
25OC1430360304.13
26WD14185481982.8272.64
27DJ1446632736.07101.21
28CB1707210253.44
29BH144126110013.76
30HR113139720027.5
31GA1699218304.13
32YA1489513405.5
33HF139748330041.26
34XH1129494304.13
35IA142636540055
36CN149508514019.26
37QD143541310013.76
38KX114472816022
39GB1698302506.88
40XC113248520027.5
tempSheet



A statement can be anywhere from 10 transactions to 2000. The system we have is limited to 16 transactions being entered at a time, per receipt.

So, I use Lastrow to obtain the number of transactions. The examples above were just different possible amounts of transactions I could have.

The main loop will ensure that all transactions are copied to the new sheet.

However, it is going to basically reprocess the set of 16 three times.

So, the code will start and look at the first 16 transactions three separate outputs with this set of 16 and then it will move to the next 16 until the total amount of transactions has been re-outputted.

Below is a sample of the output, please ignore the boxes around the data, that is just to show the three separate sections also the Source Reference, that is just the 16 transactions out xx amount. The press me button is just a placeholder as I will eventually set up a trigger for those cells that will automatically copy the output and then I can just paste it into the program.

1648821307537.png
 
Upvote 0
sorry, I was writing the above when you posted.

VBA Code:
wsSupSheet.Range("A" & lastrow). Offset([B]rNum, cNum[/B]).

This is just where I am wanting to place the data I am copying. Basically, there is the reference number and amounts that will be entered but also fixed letters and words. I have worked out the placement manually that when copied will paste into the fields already in this program. and there are three separate screens/sections that I have to paste into. The max I can enter at a time is 16 transactions. Setting up the above means I click copy and go to the program and click paste. The program was created in the DOS period, so sometimes I will skip cells (especially with section 2). The above just helps me lean how to use offset and I can move the data to the place I need it on the output.
 
Upvote 0
of course it can be done in a single loop, but this reads easier
VBA Code:
Sub DoubleLoop()
     Dim i0, i, i1, s, iSet, iTotal, a

     iSet = 16                                                  'groupsize
     a = Range(Range("AA2"), Range("AA2").End(xlDown)).Value    'read the values of a range in column AA (size unknown)
     For i = 0 To (UBound(a) - 1) / iSet                        'outer loop for the sets of 16
          For i1 = 1 To iSet                                    'inner loop (until 16 in case of a complete set)
               Cells(10 + i, i1).Value = "N" & a(i * iSet + i1, 1)     'start your groups in A10, add a "N" in front
               If i * iSet + i1 >= UBound(a) Then Exit For      'in case of an incomplete serie of 16
          Next
     Next
End Sub

i saw your recent posts, but can't respond to them right now.
 
Upvote 0
thank you both for your help, I have only started playing with VBA as a side hobby that will have some benefits with my job. I started two months ago and it helps me relax after a stressful day or week at work. Prior to this I hadn’t touch programming since university 30 years ago. So again, thanks heaps as this will allow me to get receipting caught back up and reduce my stress and will allow to focus on other task.

I will test out the code in the morning after I take my son to see Sonic 2, and I will let you know how it goes.
 
Upvote 0
oberon70
it's very similar to DOS, what was it again Basic, that first program of MS ?

VBA Code:
Sub DoubleLoop()
     Dim i0, i, i1, s, iSet, iTotal, a, O1(), O2(), O3()

     iSet = 16                                                  'groupsize

     With Range("TBL_Claims").ListObject
          a = .DataBodyRange.Value                              'read the values of this table (size unknown)
          Set sh = .Parent                                      'the sheet, that range (listobject) is in
     End With

     sh.UsedRange.Offset(, 9).ClearContents                     'clear everything at the RHS of our table

     For i = 0 To (UBound(a) - 1) / iSet                        'outer loop for the sets of 16
          ReDim O1(1 To iSet, 1 To 2)                           'start with fresh (=empty) & correct sized arrays !!!
          ReDim O2(1 To WorksheetFunction.RoundUp((iSet - 1) / 6, 0), 1 To 6)
          ReDim O3(1 To 3 * iSet, 1 To 2)

     '1st part = make per 16 3 sets of arrays (O1 to O3) ready for output
     '***************************************************
          For i1 = 1 To iSet                                    'inner loop (until 16 in case of a complete set)

               ptr = i * iSet + i1                              'pointer to know the right row in a
               If ptr > UBound(a) Then Exit For
     '1st array =16 rows with claimcounter and amount
               O1(i1, 1) = a(ptr, 1)
               O1(i1, 2) = a(ptr, 2)

     '2nd array=3 rows * 6 columns "N" & claimnumber
               ptr1 = (i1 - 1) \ 6: ptr2 = i1 - (ptr1 * 6)
               O2(ptr1 + 1, ptr2) = "N" & a(i1, 1)

     '3rd array=alternate -amount & "payment"   /    + inc Comm & "commission"
               O3((i1 - 1) * 2 + 1, 1) = -a(ptr, 2)
               O3((i1 - 1) * 2 + 1, 2) = "payment " & a(ptr, 1)
               O3(i1 * 2, 1) = a(ptr, 3)
               O3(i1 * 2, 2) = "Commission"
          Next

     '2nd part = write those 3 arrays (O1 to O3) to the sheet
     '***************************************************
          With sh.Cells(1, 10 * (1 + i))
               .Value = "Wayne tech BM7809"                     ' a title ?

               .Offset(2).Resize(UBound(O1), UBound(O1, 2)).Value = O1     '1st array = claimcounter & amount

               With .Offset(20)                                 '2nd array = 2*6+4, "N" & claimcounter
                    For i3 = 1 To 3
                         .Offset(2 * (i3 - 1)).Resize(1, 6).Value = Application.Index(O2, i3, 0)     '3 rows of 6
                    Next
               End With

               With .Offset(30)                                 '3rd array = alternating payment & commission in block of 12 = block 1-12, 13-24 and 25-36 (with 33-36 empty)
                    For i3 = 1 To 3                             '3 blocks of 12
                         .Offset((i3 - 1) * 15).Resize(12, 2).Value = Application.Index(O3, WorksheetFunction.Sequence(12, 1, (i3 - 1) * 12 + 1), Array(1, 2))
                    Next
               End With
          End With
     Next

     sh.UsedRange.EntireColumn.AutoFit                          'adjust columnwidth
End Sub
 
Upvote 0
The first code I tried out was basic on my VIC 20, which saved the data to a tape drive. I used Dos afterwards, my 1st pc had a 5 1/4 floppy then 3.5, which was great for the Sierra Games like King Quest and my first hard drive was a used drive purchased for $100.00 that was a whopping 10MB in size.

Just a question, I get an error on the line

Set sh = .parent

It tells me the variable is not defined.
 
Upvote 0
you use "option explicit", i did that as novice, now never.
so add sh in that first line "Dim ..."
 
Upvote 0

Forum statistics

Threads
1,214,375
Messages
6,119,164
Members
448,870
Latest member
max_pedreira

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top