"Reshaping" datasets in Access

mousenib

New Member
Joined
Aug 8, 2005
Messages
13
Hi,

I have a dataset that's in a "wide" format:

State, Year, Variable1, Variable2, Variable3
AL, 1990, 40, 50, 60
AR, 1980, 41, 51, 61
AK, 1970, 33, 55, 66
...

And I want it in a "long" format:

AL, 1990, Variable1, 40
AL, 1990, Variable2, 50
AL, 1990, Variable3, 60
AR, 1980, Variable1, 41
AR, 1980, Variable2, 51
AR, 1980, Variable3, 61
AK, 1970, Variable1, 33
etc...

The data is easier to read into a Pivot Table that way. Currently, I'm exporting the "wide" data from Access into Stata, reshaping it, exporting it to .csv, and then using the .csv as a basis for a Pivot Table (too many rows to import data into Excel). Ideally, I'd like to skip the Stata step altogether, but don't know if it's possible to reshape data in Access. Does anybody know a) whether this is possible and b) how to do it?

Any pointers would be appreciated. Thanks!
 

Excel Facts

Is there a shortcut key for strikethrough?
Ctrl+S is used for Save. Ctrl+5 is used for Strikethrough. Why Ctrl+5? When you use hashmarks to count |||| is 4, strike through to mean 5.
I think the only way to do it would be through code.

If you want that I'll try and knock something up and post back.
 
Upvote 0
Right, here you are.

I created your original table in Access and called it Wide.

I created another table called Flat with 4 fields - State, Year, VariableValue and VariableNo

Code:
Sub AddToFlat()
Dim db As DAO.Database
Dim fldWide As DAO.Field
Dim fldFlat As DAO.Field
Dim rstWide As DAO.Recordset
Dim rstFlat As DAO.Recordset
Dim I As Long

    Set db = CurrentDb

    Set rstWide = db.OpenRecordset("Wide")
    Set rstFlat = db.OpenRecordset("Flat")

    rstWide.MoveFirst
    
    While Not (rstWide.EOF)
        With rstFlat
            For I = 2 To rstWide.Fields.Count - 1
                .AddNew
                .Fields(0) = rstWide.Fields(0)
                .Fields(1) = rstWide.Fields(1)
                .Fields(2) = rstWide.Fields(I)
                .Fields(3) = rstWide.Fields(I).Name
                .Update
            Next I
        End With
        rstWide.MoveNext
    Wend
End Sub
 
Upvote 0
No problem.:)

Does it work, it's been a while since I've coded for Access?

It worked on your sample.

By the way it's using DAO which has actually been superseded by ADO.

There might be another method for doing this in ADO.
 
Upvote 0
It does work. One more question though - how could I modify the code to work on a query instead of a table?

Thanks, Norie!
 
Upvote 0
Is the query the source?

You can use Recordset for queries and tables.
 
Upvote 0
Right, here you are.

I created your original table in Access and called it Wide.

I created another table called Flat with 4 fields - State, Year, VariableValue and VariableNo

Code:
Sub AddToFlat()
Dim db As DAO.Database
Dim fldWide As DAO.Field
Dim fldFlat As DAO.Field
Dim rstWide As DAO.Recordset
Dim rstFlat As DAO.Recordset
Dim I As Long

    Set db = CurrentDb

    Set rstWide = db.OpenRecordset("Wide")
    Set rstFlat = db.OpenRecordset("Flat")

    rstWide.MoveFirst
    
    While Not (rstWide.EOF)
        With rstFlat
            For I = 2 To rstWide.Fields.Count - 1
                .AddNew
                .Fields(0) = rstWide.Fields(0)
                .Fields(1) = rstWide.Fields(1)
                .Fields(2) = rstWide.Fields(I)
                .Fields(3) = rstWide.Fields(I).Name
                .Update
            Next I
        End With
        rstWide.MoveNext
    Wend
End Sub

----------------------

I have used your code as is and it works great - but I want to pass a parameter to the query that supplies the "wide" data.

Here is my code:

Sub HPF_Long_File()
Dim db As DAO.Database
Dim fldWide As DAO.Field
Dim fldFlat As DAO.Field
Dim rstWide As DAO.Recordset
Dim rstFlat As DAO.Recordset
Dim I As Long
Dim Inpt As Date


Set db = CurrentDb
' gets input data

Inpt = InputBox("Enter a start date")


' run query with parameter - doesn't work

With CurrentDb.QueryDefs("qry_HPF_Transfer")
.Parameters("[Start Date]") = Inpt
.Execute
End With


' deletes all records from table HPF_Long_File

CurrentDb.Execute "DELETE from HPF_Long_File"

' opens record sets
Set rstWide = db.OpenRecordset("qry_HPF_transfer")
Set rstFlat = db.OpenRecordset("HPF_Long_File")

rstWide.MoveFirst

' moves records from query results to long file format
While Not (rstWide.EOF)
With rstFlat
For I = 4 To rstWide.Fields.Count - 1
.AddNew
.Fields(0) = rstWide.Fields(0)
.Fields(1) = rstWide.Fields(1)
.Fields(2) = rstWide.Fields(2)
.Fields(3) = rstWide.Fields(3)
.Fields(4) = rstWide.Fields(I)
.Fields(5) = rstWide.Fields(I).Name
.Update
Next I
End With
rstWide.MoveNext
Wend
End Sub


You will see that I added an input box and then try to pass that to the query. But the query doesn't work - it fails at the execute command.

And, with my limited experience, I doubt that the Set rstWide line won't work either.

Any suggestions??
 
Upvote 0

Forum statistics

Threads
1,214,375
Messages
6,119,170
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