0

I have an MS Access DB, of which I extract data from a table, and do numerous IIF/SUM calculations, per month - 20-50 calculations in Access. These calculations are done per region up to max 30+ regions.

Therefore, I create a temporary input table using GROUP BY on region which pulls for all relevant regions in a month, with the calculations. That bit all works OK.
(Table below as example. Extends out for more measures, Regions, RPTDates.

Process will be run on multiple datasource files, each with different number of Measures, Regions and RPTDates - nothing will be the same from datasource to datasource.)

Region RPTDate Measure1 Measure2 Measure3
RegionA 28/02/2021 10 8 4
RegionB 28/02/2021 25 2 10
RegionC 28/02/2021 100 50 25

I have previously sourced a great transpose function here (thanks to original author), and have it working when I only have one line of data. It outputs all columns/fields in the array to another output table:

What I would like to do is to run a process where each row will run through the Transpose process separately with the results to the output table, for as many rows as are in the input table.

Desired output (sorting is irrelevant right now):

Region RPTDate MeasureID RPTValue
RegionA 28/02/2021 Measure1 10
RegionB 28/02/2021 Measure1 25
RegionC 28/02/2021 Measure1 100
RegionA 28/02/2021 Measure2 8
RegionB 28/02/2021 Measure2 2
RegionC 28/02/2021 Measure2 50
RegionA 28/02/2021 Measure3 4
RegionB 28/02/2021 Measure3 10
RegionC 28/02/2021 Measure3 25

Current code:

Function transpose_DVC_L3R()


' Sub transpose_DVC_L3R()
' Transpose the Monthly Results for Data Source CODE:  DVC, Level 3 REGIONS Results

    Dim db As DAO.Database
    Dim tdfNewDef As DAO.TableDef
    Dim fldNewField As DAO.Field
    Dim rstSource As DAO.Recordset
    Dim rstTarget As DAO.Recordset
    Dim i As Integer, j As Integer
    Dim strSource As String
    Dim strTarget As String
    Dim sqlcode As String
    
    Dim t_array() As Variant
    Dim t_no_of_rows As Integer
    Dim t_no_of_columns As Integer
    Dim s_no_of_rows As Integer
    Dim s_no_of_columns As Integer
    
    On Error GoTo Transposer_Err
    
    
    ' Specific individual INPUT and OUTPUT Tables for Transpose function
    strSource = "TBL_DVC41X_DataSource_L3_Regions_INPUT"
    strTarget = "TBL_DVC41X_CurrMthOUTPUT_L3R_OUTPUT"
    
    
    ' *** UPDATE INPUT TABLE name here
      
    Set db = CurrentDb()
    Set rstSource = db.OpenRecordset("SELECT * FROM TBL_DVC41X_DataSource_L3_Regions_INPUT", dbOpenDynaset)
    
    
    
    rstSource.MoveLast
    
    t_no_of_rows = rstSource.Fields.Count
    t_no_of_columns = rstSource.RecordCount + 1
    s_no_of_columns = rstSource.Fields.Count
    s_no_of_rows = rstSource.RecordCount + 1


    ' *** UPDATE OUTPUT TABLE name here
    DoCmd.SetWarnings False
    sqlcode = "DELETE TBL_DVC41X_CurrMthOUTPUT_L3R_OUTPUT.* FROM TBL_DVC41X_CurrMthOUTPUT_L3R_OUTPUT"
   DoCmd.RunSQL sqlcode
    DoCmd.SetWarnings True

    ReDim t_array(t_no_of_rows, t_no_of_columns)

    ' Fill the first field of the array with
    ' field names from the original table.
    For i = 0 To t_no_of_rows - 1
       t_array(i, 0) = rstSource.Fields(i).Name

    Next i
    
    rstSource.MoveFirst
    
    ' Fill each column of the array
    ' with a record from the original table.
    For j = 0 To t_no_of_rows - 1
        ' Begin with the second field, because the first field
        ' already contains the field names.
        For i = 1 To t_no_of_columns - 1
       '     Debug.Print i & " " & j
      
            t_array(j, i) = rstSource.Fields(j)
   
            rstSource.MoveNext
        Next i
        rstSource.MoveFirst
    Next j
    
    ' Fill the target table with fields from the array
    Set rstTarget = db.OpenRecordset(strTarget)
    For j = 0 To t_no_of_rows - 1
        rstTarget.AddNew
        
        For i = 0 To t_no_of_columns - 1
  
            rstTarget.Fields(i) = t_array(j, i)
        Next i
        rstTarget.Update
    Next j
    
    db.Close
    
    'MsgBox ("finished")
' Exit Sub
Exit Function

Transposer_Err:

   Select Case Err
      Case 3010
         MsgBox "The table " & strTarget & " already exists."
      Case 3078
         MsgBox "The table " & strSource & " doesn't exist."
      Case Else
         MsgBox CStr(Err) & " " & Err.Description
   End Select

   'Exit Sub
   'Exit Function

' End Sub

End Function

Is there a way to identify next row and do this within the transpose function, and loop?

Is there a way to identify and isolate the next row of the input table, and send it to a separate table to make a new input table?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • 1
    Edit question to show example of raw source data and desired output. Post the code you have that processes the one line. From what you have shown, looks like a UNION query could produce output. – June7 Aug 12 '21 at 07:21
  • 2
    You may want to use a recordset to loop through the "steering" set of data performing the actions required. But without any raw data and existing code, nobody can advise you!! – Applecore Aug 12 '21 at 09:53
  • Original post editted to add original transpose coding and example output. Thanks, – witchdoctor Aug 13 '21 at 04:40
  • 1
    The keyword you are looking for is `Unpivot`. It needs no VBA. https://stackoverflow.com/questions/7255423/how-to-simulate-unpivot-in-access – Andre Aug 13 '21 at 08:43
  • Thank you very much, Andre, that was exactly the answer I needed! Unpivot and UNION ALL saves the day! Have a good weekend. – witchdoctor Aug 13 '21 at 10:05

0 Answers0