to prefix, I am incredibly new to VBA (around 1 month on/off experience). I managed to write some code to aggregate lines in an array based on certain conditions, which would then be implemented into some code in an access database. Much to my demise, when trying to implement, I quickly learned that Excel VBA and Access VBA do not work the same way, and I am having trouble trying to replace the array reference with a recordset reference. Any help would be appreciated.
Here is a snippet of my placeholder data, which will then be fed from access with the same columns: Placeholder Dataset
Below is the code in excel VBA I used to filter for unqiue portfolio numbers and aggregating all lines with the same portfolio number. Currently the output has one line with the correct "Min" (the "Max" is set to 100), and a second line with the correct "Max" (the "Min" is set to 0). These need to be combined, to have one line with the correct min and max, deleting any other lines with the same portfolio number:
Sub RemDup()
Dim raw_array, unq_array, temp, min_wght, max_wght, temp2, site_name, asset_class, neutral, class_weight, min_raw, max_raw As Variant
Dim c_row, c_row2, r_length, c_length, unq_row, unq_row2 As Long
'Placeholder. The data for raw_array should come from an acces recordset.
raw_array = ThisWorkbook.Sheets("Sheet1").Range("A1").CurrentRegion.Value
unq_array = ThisWorkbook.Sheets("Sheet1").Range("A1:G1").Value
'Main part 1 of code. Filter unique values and place into second array
For c_row = LBound(raw_array, 1) To UBound(raw_array, 1)
site_name = raw_array(c_row, 1)
temp = raw_array(c_row, 2)
asset_class = raw_array(c_row, 3)
min_wght = raw_array(c_row, 4)
max_wght = raw_array(c_row, 5)
neutral = raw_array(c_row, 6)
class_weight = raw_array(c_row, 7)
For c_row2 = LBound(unq_array, 1) To UBound(unq_array, 1)
If Not temp = unq_array(c_row2, 2) Then
GoTo skipsubloop
Else
GoTo skiploop
End If
skipsubloop:
Next c_row2
r_length = UBound(unq_array, 1)
c_length = UBound(unq_array, 2)
unq_array = Application.Transpose(unq_array)
ReDim Preserve unq_array(1 To c_length, 1 To r_length + 1)
unq_array = Application.Transpose(unq_array)
unq_array(r_length + 1, 1) = site_name
unq_array(r_length + 1, 2) = temp
unq_array(r_length + 1, 3) = asset_class
unq_array(r_length + 1, 4) = min_wght
unq_array(r_length + 1, 5) = max_wght
unq_array(r_length + 1, 6) = neutral
unq_array(r_length + 1, 7) = class_weight
skiploop:
Next c_row
'Main part 2 of code. Use unique values to aggregate rows according to certain condition.
For unq_row = LBound(unq_array, 1) + 1 To UBound(unq_array, 1)
temp2 = unq_array(unq_row, 2)
For unq_row2 = LBound(raw_array, 1) + 1 To UBound(raw_array, 1)
If temp2 = raw_array(unq_row2, 2) Then
min_raw = raw_array(unq_row2, 4)
max_raw = raw_array(unq_row2, 5)
unq_array(unq_row, 4) = WorksheetFunction.Max(min_raw, unq_array(unq_row, 4))
unq_array(unq_row, 5) = WorksheetFunction.Min(max_raw, unq_array(unq_row, 5))
End If
Next unq_row2
Next unq_row
End Sub
the then looks something like this: Output data
I know effectively nothing about SQL and Access. I'm not looking for someone to translate the whole code for me, I'm just struggling to see where to even start with the process, or if my approach is completely wrong. Even some pointers would be appreciated, or perhaps even knowing if this is out of the scope for a beginner would help.
Thank everyone in advance!
Added - since your source data is in Access you can just use SQL for the rollup. Something like:
select sitename, portfolio, assetclass, Min([Min]) as minVal,
Max([Max]) as maxVal, Neutral, Weight
from tablename
group by sitename, portfolio, assetclass, Neutral, Weight
Without really addressing the bigger picture of what it means to move from Excel to Access...
Since you're only using Transpose
as a workaround so you can resize unq_array
, you can instead do that directly using a Function:
Sub tester()
Dim arr
arr = Range("A1:D5").Value 'Testing this in excel...
Debug.Print UBound(arr, 1) '5
arr = AddRows(arr)
Debug.Print UBound(arr, 1) '6
End Sub
'Resize first dimension of 2D array `arr` by `numrows`
Function AddRows(arr, Optional numrows As Long = 1)
Dim newArr, r As Long, c As Long
ReDim newArr(1 To UBound(arr, 1) + numrows, 1 To UBound(arr, 2))
For r = 1 To UBound(arr, 1)
For c = 1 To UBound(arr, 2)
newArr(r, c) = arr(r, c)
Next c
Next r
AddRows = newArr
End Function
Transpose:
'transpose a 2D array
Function MyTranspose(arr)
Dim newArr, r As Long, c As Long, lbc As Long, lbr As Long, ubc As Long, ubr As Long
lbr = LBound(arr, 1): ubr = UBound(arr, 1)
lbc = LBound(arr, 2): ubc = UBound(arr, 2)
ReDim newArr(lbc To ubc, lbr To ubr)
For r = lbr To ubr
For c = lbc To ubc
newArr(c, r) = arr(r, c) 'transpose
Next c
Next r
MyTranspose = newArr
End Function