VBA offcut calculation

Cuprian

New Member
Joined
Oct 25, 2021
Messages
20
Office Version
  1. 365
  2. 2016
Platform
  1. Windows
Hi,
Let's say I have this set of data:
1635598121209.png


In colum E I want to display offcut with data from equation "B1 - all length with Nr 1, Nr 2, Nr 3, etc.)
Example:
E3 = B1- B3-B4-B5
E4 = B1- B6-B7-B8 etc.
Any ideas how can I acheive it using VBA?
 
Trying to use the following 1 line:

VBA Code:
Range("G" & TableStartRow & ":G" & LastRowD).Value = Range("B1") - Application.WorksheetFunction.SumIf(Range("A" & TableStartRow & ":A" & LastRowA), Range("D3"), Range("B" & TableStartRow & ":B" & LastRowA))

But I can't figure out how to get the 'Range("D3")' to be incremented without using a loop.
 
Upvote 0

Excel Facts

Select a hidden cell
Somehide hide payroll data in column G? Press F5. Type G1. Enter. Look in formula bar while you arrow down through G.
VBA Code:
Sub Test()
'
    Dim A_ColumnLoopCounter As Long
    Dim D_ColumnLoopCounter As Long
    Dim LastRowA            As Long
    Dim LastRowD            As Long
    Dim SubtractTotal       As Long
    Dim TableStartRow       As Long
'
    LastRowA = Cells(Rows.Count, "A").End(xlUp).Row
    LastRowD = Cells(Rows.Count, "D").End(xlUp).Row
    TableStartRow = 3
'
    For D_ColumnLoopCounter = 1 To Range("D" & LastRowD)
        For A_ColumnLoopCounter = TableStartRow To LastRowA
            If Range("A" & A_ColumnLoopCounter) = D_ColumnLoopCounter Then SubtractTotal = SubtractTotal + Range("B" & A_ColumnLoopCounter)
        Next
'
        Range("E" & D_ColumnLoopCounter + 2) = Range("B1") - SubtractTotal
        SubtractTotal = 0
    Next
End Sub


bluefeather.xlsm
ABCDEF
112050
2NrLengthNrcut
3150001120
4150002135
5119303135
6250004200
7250005505
82191562050
93500072050
103500082050
113191592050
1245000102050
1345000112050
1441850
1555000
1655000
1751545
1865000
1965000
2075000
2175000
2285000
2385000
2495000
2595000
26105000
27105000
28115000
29115000
30
Sheet3
Wow, thank you very much. Code works well when "raw" data, but when I inserted table on that data, program stopped working :/
 
Upvote 0
Wow, thank you very much. Code works well when "raw" data, but when I inserted table on that data, program stopped working :/
There have been several good code suggestions offered in this thread. If none of them seem to work for you, perhaps you could upload a sample of your file with the table. Provide the link to the file and we can take a look at it for you.
 
Upvote 0
In the mean time, you can try the following workaround:

VBA Code:
Sub NewTestForTable()
'
    Dim A_ColumnLoopCounter As Long, D_ColumnLoopCounter    As Long
    Dim LastRowA            As Long, LastRowD               As Long
    Dim SubtractTotal       As Long
    Dim TableStartRow       As Long
    Dim DestinationSheet    As String
    Dim MyTableName         As String, MyTableRange         As String
'
    DestinationSheet = "Sheet4"                                                     ' <--- Set this to the proper sheet name
    MyTableName = "myTable1"                                                        ' <--- Set this to your Table Name
    MyTableRange = "A2:D29"                                                         ' <--- Set this to the Range of the Table
'
    Sheets(DestinationSheet).ListObjects(MyTableName).Unlist                        ' Temporarily turn Table back to a Range
'
    LastRowA = Sheets(DestinationSheet).Range("A" & Rows.Count).End(xlUp).Row       ' Get Last Row of column A
    LastRowD = Sheets(DestinationSheet).Range("D" & Rows.Count).End(xlUp).Row       ' Get Last Row of column D
    TableStartRow = 3                                                               ' Set start row of Table
'
    For D_ColumnLoopCounter = 1 To Sheets(DestinationSheet).Range("D" & LastRowD)   ' Loop for the D column
        For A_ColumnLoopCounter = TableStartRow To LastRowA                         '   Loop for the A column
            If Sheets(DestinationSheet).Range("A" & A_ColumnLoopCounter) = _
                D_ColumnLoopCounter Then SubtractTotal = SubtractTotal + Sheets(DestinationSheet).Range("B" & A_ColumnLoopCounter)  ' Keep total to subtract
        Next
'
        Sheets(DestinationSheet).Range("E" & D_ColumnLoopCounter + 2) = Sheets(DestinationSheet).Range("B1") - SubtractTotal        '   Display Result in column E
        SubtractTotal = 0                                                                                                   '   Reset SubtractTotal back to zero
    Next
'
    Sheets(DestinationSheet).ListObjects.Add(xlSrcRange, Sheets(DestinationSheet).Range(MyTableRange), , xlYes).Name = MyTableName  ' ReCreate Table
End Sub


Be sure to set those top 3 variables that have arrows in the comments to the right. ;)
 
Upvote 0
In the mean time, you can try the following workaround:

VBA Code:
Sub NewTestForTable()
'
    Dim A_ColumnLoopCounter As Long, D_ColumnLoopCounter    As Long
    Dim LastRowA            As Long, LastRowD               As Long
    Dim SubtractTotal       As Long
    Dim TableStartRow       As Long
    Dim DestinationSheet    As String
    Dim MyTableName         As String, MyTableRange         As String
'
    DestinationSheet = "Sheet4"                                                     ' <--- Set this to the proper sheet name
    MyTableName = "myTable1"                                                        ' <--- Set this to your Table Name
    MyTableRange = "A2:D29"                                                         ' <--- Set this to the Range of the Table
'
    Sheets(DestinationSheet).ListObjects(MyTableName).Unlist                        ' Temporarily turn Table back to a Range
'
    LastRowA = Sheets(DestinationSheet).Range("A" & Rows.Count).End(xlUp).Row       ' Get Last Row of column A
    LastRowD = Sheets(DestinationSheet).Range("D" & Rows.Count).End(xlUp).Row       ' Get Last Row of column D
    TableStartRow = 3                                                               ' Set start row of Table
'
    For D_ColumnLoopCounter = 1 To Sheets(DestinationSheet).Range("D" & LastRowD)   ' Loop for the D column
        For A_ColumnLoopCounter = TableStartRow To LastRowA                         '   Loop for the A column
            If Sheets(DestinationSheet).Range("A" & A_ColumnLoopCounter) = _
                D_ColumnLoopCounter Then SubtractTotal = SubtractTotal + Sheets(DestinationSheet).Range("B" & A_ColumnLoopCounter)  ' Keep total to subtract
        Next
'
        Sheets(DestinationSheet).Range("E" & D_ColumnLoopCounter + 2) = Sheets(DestinationSheet).Range("B1") - SubtractTotal        '   Display Result in column E
        SubtractTotal = 0                                                                                                   '   Reset SubtractTotal back to zero
    Next
'
    Sheets(DestinationSheet).ListObjects.Add(xlSrcRange, Sheets(DestinationSheet).Range(MyTableRange), , xlYes).Name = MyTableName  ' ReCreate Table
End Sub


Be sure to set those top 3 variables that have arrows in the comments to the right. ;)
this code worked. Thank you for your help!
 
Upvote 0
I have another case (connected with the previous one).
d (version 1).xlsb.xlsm
ABCDEFGHIJKLMNOP
112050
2NrLengthNrLength1st cut2nd cut3rd cut4th cut5th cut6th cut7th cut
31500011201500050001930120
41500021352500050001915120
51193031353500050001915120
62500042004500050001850120
72500055055500050001545505
821915620506500050002050
935000720507500050002050
1035000820508500050002050
1131915920509500050002050
124500010205010500050002050
134500011205011500050002050
1441850
1555000
1655000
1751545nr of patterns
18650001x500050001930120
19650002x500050001915120
20750001x500050001850120
21750001x500050001545505
22850006x500050002050
2385000
2495000
2595000
26105000
27105000
28115000
29115000
Arkusz1


I'm trying to combine the Data from columns A:B with the data from columns D:E and display it as below:

d (version 1).xlsb.xlsm
HIJKLMNOP
21st cut2nd cut3rd cut4th cut5th cut6th cut7th cut
31500050001930120
42500050001915120
53500050001915120
64500050001850120
75500050001545505
86500050002050
97500050002050
108500050002050
119500050002050
1210500050002050
1311500050002050
Arkusz1

I've been trying to do it with index+match formulas but it did not work. I would be very thankful if you could tell me how to do it using vba code that will work with every data i put in columns A:B and C:D. Btw. results in column D were created using your code:

VBA Code:
Sub Test()

 
 Dim A_ColumnLoopCounter As Long, D_ColumnLoopCounter    As Long
    Dim LastRowA            As Long, LastRowD               As Long
    Dim SubtractTotal       As Long
    Dim TableStartRow       As Long
    Dim DestinationSheet    As String
    Dim MyTableName         As String, MyTableRange         As String
    lr = Cells.Find("*", Cells(1, 1), xlFormulas, xlPart, xlByRows, xlPrevious, False).Row
    DestinationSheet = "Arkusz1"                                                     ' <--- Set this to the proper sheet name
    MyTableName = "Tabela3"                                                        ' <--- Set this to your Table Nam
    MyTableRange = "D2:E" & lr                                                       ' <--- Set this to the Range of the Table
'
    Sheets(DestinationSheet).ListObjects(MyTableName).Unlist                        ' Temporarily turn Table back to a Range
'
    LastRowA = Sheets(DestinationSheet).Range("A" & Rows.Count).End(xlUp).Row       ' Get Last Row of column A
    LastRowD = Sheets(DestinationSheet).Range("D" & Rows.Count).End(xlUp).Row       ' Get Last Row of column D
    TableStartRow = 3                                                               ' Set start row of Table
'
    For D_ColumnLoopCounter = 1 To Sheets(DestinationSheet).Range("D" & LastRowD)   ' Loop for the D column
        For A_ColumnLoopCounter = TableStartRow To LastRowA                         '   Loop for the A column
            If Sheets(DestinationSheet).Range("A" & A_ColumnLoopCounter) = _
                D_ColumnLoopCounter Then SubtractTotal = SubtractTotal + Sheets(DestinationSheet).Range("B" & A_ColumnLoopCounter)  ' Keep total to subtract
        Next
'
        Sheets(DestinationSheet).Range("E" & D_ColumnLoopCounter + 2) = Sheets(DestinationSheet).Range("B1") - SubtractTotal        '   Display Result in column E
        SubtractTotal = 0                                                                                                   '   Reset SubtractTotal back to zero
    Next

    Sheets(DestinationSheet).ListObjects.Add(xlSrcRange, Sheets(DestinationSheet).Range(MyTableRange), , xlYes).Name = MyTableName  ' ReCreate Table

End Sub
 
Upvote 0
How about this:

VBA Code:
Sub Test2()
'
    Dim A_ColumnLoopCounter         As Long, D_ColumnLoopCounter    As Long
    Dim Column_E_Array_Slot         As Long
    Dim CutsArrayColumnCounter      As Long, CutsArrayMaxColumn     As Long, CutsArrayResultsStartColumn As Long
    Dim LastRowD                    As Long, LastRowInSheet         As Long
    Dim SubtractTotal               As Long
    Dim TableStartRow               As Long
    Dim DestinationSheet            As String
    Dim MyTableName                 As String, MyTableRange         As String
    Dim StartingValue               As String
    Dim Columns_AB_Array            As Variant
    Dim Column_D_Array              As Variant, Column_E_Array      As Variant
    Dim CutsArray                   As Variant
    Dim wsDestination               As Worksheet
'
    Set wsDestination = Sheets("Arkusz1")                                               ' <--- Set this to the proper sheet name
    MyTableName = "Tabela3"                                                             ' <--- Set this to your Table Nam
'
    LastRowInSheet = wsDestination.Cells.Find("*", Cells(1, 1), xlFormulas, xlPart, xlByRows, xlPrevious, False).Row    ' Find last used Row in sheet
    LastRowD = wsDestination.Range("D" & Rows.Count).End(xlUp).Row                      ' Get Last used Row of column D
'
    MyTableRange = "D2:E" & LastRowInSheet                                              ' <--- Set this to the Range of the Table
    TableStartRow = 3                                                                   ' <--- Set this to start row of data in the Table
    StartingValue = wsDestination.Range("B1")                                           ' <--- Set this to the Address of Value that will be subtracted from
'
    Column_E_Array_Slot = 0                                                             ' Initialize slot counter for Column_E_Array
    CutsArrayColumnCounter = 0                                                          ' Initialize CutsArrayColumnCounter
    CutsArrayMaxColumn = 0                                                              ' Initialize CutsArrayMaxColumn
    CutsArrayResultsStartColumn = 9                                                     ' Set start column number to display CutsArray
'
    On Error Resume Next                                                                ' If Table doesn't exist then ignore error resulting from next line
    wsDestination.ListObjects(MyTableName).Unlist                                       ' Temporarily turn Table back into a Range
    On Error GoTo 0                                                                     ' Resume Excel Error Handling
'
    Columns_AB_Array = wsDestination.Range("A" & TableStartRow & ":B" & LastRowInSheet) ' Load data from A&B columns into 2 dimensional 1 based array RC
    Column_D_Array = wsDestination.Range("D" & TableStartRow & ":D" & LastRowD)         ' Load data from D column into 2 dimensional 1 based array RC
    ReDim Column_E_Array(1 To LastRowD)                                                 ' Set size of Column_E_Array 1 dimensional array 1 based
    ReDim CutsArray(1 To LastRowD, 1 To 50)                                             ' Set CutsArray to a 2 dimensional 1 based oversized array
'
    For D_ColumnLoopCounter = LBound(Column_D_Array) To UBound(Column_D_Array)          ' Loop for the Column_D_Array
        For A_ColumnLoopCounter = LBound(Columns_AB_Array) To UBound(Columns_AB_Array)  '   Loop for the Columns_AB_Array
            If Columns_AB_Array(A_ColumnLoopCounter, 1) = Column_D_Array(D_ColumnLoopCounter, 1) Then   ' If column A value = column D value then ...
                SubtractTotal = SubtractTotal + Columns_AB_Array(A_ColumnLoopCounter, 2)    ' Keep total to subtract
'
                CutsArrayColumnCounter = CutsArrayColumnCounter + 1                                                 '   Increment CutsArrayColumnCounter
                If CutsArrayColumnCounter > CutsArrayMaxColumn Then CutsArrayMaxColumn = CutsArrayColumnCounter     '   Keep track of CutsArrayMaxColumn
                CutsArray(D_ColumnLoopCounter, CutsArrayColumnCounter) = Columns_AB_Array(A_ColumnLoopCounter, 2)   '   Save cut value to CutsArray
            End If
        Next
'
        Column_E_Array_Slot = Column_E_Array_Slot + 1                                                               ' Increment Column_E_Array_Slot counter
        Column_E_Array(Column_E_Array_Slot) = StartingValue - SubtractTotal                                         ' Save result into Column_E_Array
        CutsArray(D_ColumnLoopCounter, CutsArrayColumnCounter + 1) = Column_E_Array(Column_E_Array_Slot)            ' Also Save result into CutsArray
        If CutsArrayColumnCounter + 1 > CutsArrayMaxColumn Then CutsArrayMaxColumn = CutsArrayColumnCounter + 1     ' If new CutsArrayMaxColumn, save it
        SubtractTotal = 0                                                                                           ' Reset SubtractTotal back to zero
        CutsArrayColumnCounter = 0                                                                                  ' Reset CutsArrayColumnCounter back to zero
    Next
'
    ReDim Preserve CutsArray(1 To LastRowD, 1 To CutsArrayMaxColumn)                                                ' Resize CutsArray to actual used size
'
    wsDestination.Range("E" & TableStartRow & ":E" & LastRowD) = Application.Transpose(Column_E_Array)              ' Display Column_E_Array to column E
    wsDestination.Range("H" & TableStartRow & ":H" & LastRowD) = Column_D_Array                                     ' Display Column_D_Array to column H
    wsDestination.Range(Cells(TableStartRow, CutsArrayResultsStartColumn), _
        Cells(LastRowD, CutsArrayResultsStartColumn + CutsArrayMaxColumn - 1)) = CutsArray     ' Display CutsArray to column I range
'
    wsDestination.ListObjects.Add(xlSrcRange, wsDestination.Range(MyTableRange), , xlYes).Name = MyTableName  ' ReCreate Table
End Sub

It combines the previous code as well as the code to handle your new requested code.

In other words, It will fill in E3:L13 for you. Should be faster also because I redesigned the code to use arrays.
 
Upvote 0
How about this:

VBA Code:
Sub Test2()
'
    Dim A_ColumnLoopCounter         As Long, D_ColumnLoopCounter    As Long
    Dim Column_E_Array_Slot         As Long
    Dim CutsArrayColumnCounter      As Long, CutsArrayMaxColumn     As Long, CutsArrayResultsStartColumn As Long
    Dim LastRowD                    As Long, LastRowInSheet         As Long
    Dim SubtractTotal               As Long
    Dim TableStartRow               As Long
    Dim DestinationSheet            As String
    Dim MyTableName                 As String, MyTableRange         As String
    Dim StartingValue               As String
    Dim Columns_AB_Array            As Variant
    Dim Column_D_Array              As Variant, Column_E_Array      As Variant
    Dim CutsArray                   As Variant
    Dim wsDestination               As Worksheet
'
    Set wsDestination = Sheets("Arkusz1")                                               ' <--- Set this to the proper sheet name
    MyTableName = "Tabela3"                                                             ' <--- Set this to your Table Nam
'
    LastRowInSheet = wsDestination.Cells.Find("*", Cells(1, 1), xlFormulas, xlPart, xlByRows, xlPrevious, False).Row    ' Find last used Row in sheet
    LastRowD = wsDestination.Range("D" & Rows.Count).End(xlUp).Row                      ' Get Last used Row of column D
'
    MyTableRange = "D2:E" & LastRowInSheet                                              ' <--- Set this to the Range of the Table
    TableStartRow = 3                                                                   ' <--- Set this to start row of data in the Table
    StartingValue = wsDestination.Range("B1")                                           ' <--- Set this to the Address of Value that will be subtracted from
'
    Column_E_Array_Slot = 0                                                             ' Initialize slot counter for Column_E_Array
    CutsArrayColumnCounter = 0                                                          ' Initialize CutsArrayColumnCounter
    CutsArrayMaxColumn = 0                                                              ' Initialize CutsArrayMaxColumn
    CutsArrayResultsStartColumn = 9                                                     ' Set start column number to display CutsArray
'
    On Error Resume Next                                                                ' If Table doesn't exist then ignore error resulting from next line
    wsDestination.ListObjects(MyTableName).Unlist                                       ' Temporarily turn Table back into a Range
    On Error GoTo 0                                                                     ' Resume Excel Error Handling
'
    Columns_AB_Array = wsDestination.Range("A" & TableStartRow & ":B" & LastRowInSheet) ' Load data from A&B columns into 2 dimensional 1 based array RC
    Column_D_Array = wsDestination.Range("D" & TableStartRow & ":D" & LastRowD)         ' Load data from D column into 2 dimensional 1 based array RC
    ReDim Column_E_Array(1 To LastRowD)                                                 ' Set size of Column_E_Array 1 dimensional array 1 based
    ReDim CutsArray(1 To LastRowD, 1 To 50)                                             ' Set CutsArray to a 2 dimensional 1 based oversized array
'
    For D_ColumnLoopCounter = LBound(Column_D_Array) To UBound(Column_D_Array)          ' Loop for the Column_D_Array
        For A_ColumnLoopCounter = LBound(Columns_AB_Array) To UBound(Columns_AB_Array)  '   Loop for the Columns_AB_Array
            If Columns_AB_Array(A_ColumnLoopCounter, 1) = Column_D_Array(D_ColumnLoopCounter, 1) Then   ' If column A value = column D value then ...
                SubtractTotal = SubtractTotal + Columns_AB_Array(A_ColumnLoopCounter, 2)    ' Keep total to subtract
'
                CutsArrayColumnCounter = CutsArrayColumnCounter + 1                                                 '   Increment CutsArrayColumnCounter
                If CutsArrayColumnCounter > CutsArrayMaxColumn Then CutsArrayMaxColumn = CutsArrayColumnCounter     '   Keep track of CutsArrayMaxColumn
                CutsArray(D_ColumnLoopCounter, CutsArrayColumnCounter) = Columns_AB_Array(A_ColumnLoopCounter, 2)   '   Save cut value to CutsArray
            End If
        Next
'
        Column_E_Array_Slot = Column_E_Array_Slot + 1                                                               ' Increment Column_E_Array_Slot counter
        Column_E_Array(Column_E_Array_Slot) = StartingValue - SubtractTotal                                         ' Save result into Column_E_Array
        CutsArray(D_ColumnLoopCounter, CutsArrayColumnCounter + 1) = Column_E_Array(Column_E_Array_Slot)            ' Also Save result into CutsArray
        If CutsArrayColumnCounter + 1 > CutsArrayMaxColumn Then CutsArrayMaxColumn = CutsArrayColumnCounter + 1     ' If new CutsArrayMaxColumn, save it
        SubtractTotal = 0                                                                                           ' Reset SubtractTotal back to zero
        CutsArrayColumnCounter = 0                                                                                  ' Reset CutsArrayColumnCounter back to zero
    Next
'
    ReDim Preserve CutsArray(1 To LastRowD, 1 To CutsArrayMaxColumn)                                                ' Resize CutsArray to actual used size
'
    wsDestination.Range("E" & TableStartRow & ":E" & LastRowD) = Application.Transpose(Column_E_Array)              ' Display Column_E_Array to column E
    wsDestination.Range("H" & TableStartRow & ":H" & LastRowD) = Column_D_Array                                     ' Display Column_D_Array to column H
    wsDestination.Range(Cells(TableStartRow, CutsArrayResultsStartColumn), _
        Cells(LastRowD, CutsArrayResultsStartColumn + CutsArrayMaxColumn - 1)) = CutsArray     ' Display CutsArray to column I range
'
    wsDestination.ListObjects.Add(xlSrcRange, wsDestination.Range(MyTableRange), , xlYes).Name = MyTableName  ' ReCreate Table
End Sub

It combines the previous code as well as the code to handle your new requested code.

In other words, It will fill in E3:L13 for you. Should be faster also because I redesigned the code to use arrays.
Thanks again!

I have the last request. Could you please tell me where to change the code to display results like this (removing duplicated cuts patterns):
1636044203732.png
 
Upvote 0

Forum statistics

Threads
1,215,956
Messages
6,127,931
Members
449,411
Latest member
AppellatePerson

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