VBA to format survey data

tparmbru22

New Member
Joined
Sep 7, 2017
Messages
15
I need help creating VBA to format survey data from an excel output. Below are examples of the data and the final format that I'm looking to achieve.

The data in columns 1-3 will need to repeat as needed based on the information provided in columns 4-9.
Columns 4-6, the header is the "category" and the data is the "issue".
Columns 7-9, the "category" will all be "Expense" but the data needs to be combined into "issue".

Appreciate any help with this request.

Survey data
DateIDNameConstructionITMarketingExpense PartExpense QtyExpense Reason
01/12/22​
1234​
Joe SmithMissing drywallMissing sign kit10001,Binders
1​
Missing
01/25/22​
5678​
Jane DoeMissing monitorLabels
02/02/22​
2468​
Mike SmithWiringPinpad broken10007,Receipt tape
5​
Lost
02/15/22​
3692​
Linda JohnsonLabels10004,Pens
20​
Missing

Final formatted data
DateIDNameCategoryIssue
01/12/22​
1234​
Joe SmithConstructionMissing drywall
01/12/22​
1234​
Joe SmithMarketingMissing sign kit
01/12/22​
1234​
Joe SmithExpense10001,Binders - 1 - Missing
01/25/22​
5678​
Jane DoeITMissing monitor
01/25/22​
5678​
Jane DoeMarketingLabels
02/02/22​
2468​
Mike SmithConstructionWiring
02/02/22​
2468​
Mike SmithITPinpad broken
02/02/22​
2468​
Mike SmithExpense10007,Receipt tap - 5 - Lost
02/15/22​
3692​
Linda JohnsonMarketingLabels
02/15/22​
3692​
Linda JohnsonExpense10004,Pens - 20 - Missing
 

Excel Facts

Control Word Wrap
Press Alt+Enter to move to a new row in a cell. Lets you control where the words wrap.
Change the sheet names to suit your needs.
Rich (BB code):
Sub FormatData()
    Application.ScreenUpdating = False
    Dim desWS As Worksheet, srcWS As Worksheet, r As Long, c As Long, x As Long, y As Long, arr As Variant
    Set srcWS = Sheets("Sheet1")
    Set desWS = Sheets("Sheet2")
    desWS.Range("A1:E1") = Array("Date", "ID", "Name", "Category", "Issue")
    desWS.UsedRange.Offset(1).ClearContents
    With srcWS
        arr = .Range("A1", .Range("A" & .Rows.Count).End(xlUp)).Resize(, 9).Value
        For r = 2 To UBound(arr)
            x = WorksheetFunction.CountA(.Range("D" & r & ":F" & r))
            If WorksheetFunction.CountA(.Range("G" & r & ":I" & r)) > 0 Then y = 1
            With desWS
                .Cells(.Rows.Count, "A").End(xlUp).Offset(1).Resize(x + y).Value = (arr(r, 1))
                .Cells(.Rows.Count, "B").End(xlUp).Offset(1).Resize(x + y).Value = (arr(r, 2))
                .Cells(.Rows.Count, "C").End(xlUp).Offset(1).Resize(x + y).Value = (arr(r, 3))
                For c = 4 To 6
                    If arr(r, c) <> "" Then
                        .Cells(.Rows.Count, "D").End(xlUp).Offset(1).Value = (arr(1, c))
                        .Cells(.Rows.Count, "E").End(xlUp).Offset(1).Value = (arr(r, c))
                    End If
                Next c
                If y > 0 Then
                    .Cells(.Rows.Count, "D").End(xlUp).Offset(1).Value = "Expense"
                    .Cells(.Rows.Count, "E").End(xlUp).Offset(1).Value = Join(Application.Transpose(Application.Transpose(srcWS.Range("G" & r & ":I" & r).SpecialCells(xlCellTypeConstants).Value)), "-")
                End If
                y = 0
            End With
        Next r
    End With
    Application.ScreenUpdating = True
End Sub
 
Upvote 0
Mumps,

Do you hire out to help with spreadsheets? If so I have a couple spreadsheets I have been working on that need some assistance that is beyond me. Let me know the best means of contacting you.

thank you,
Joe
 
Upvote 0
Change the sheet names to suit your needs.
Rich (BB code):
Sub FormatData()
    Application.ScreenUpdating = False
    Dim desWS As Worksheet, srcWS As Worksheet, r As Long, c As Long, x As Long, y As Long, arr As Variant
    Set srcWS = Sheets("Sheet1")
    Set desWS = Sheets("Sheet2")
    desWS.Range("A1:E1") = Array("Date", "ID", "Name", "Category", "Issue")
    desWS.UsedRange.Offset(1).ClearContents
    With srcWS
        arr = .Range("A1", .Range("A" & .Rows.Count).End(xlUp)).Resize(, 9).Value
        For r = 2 To UBound(arr)
            x = WorksheetFunction.CountA(.Range("D" & r & ":F" & r))
            If WorksheetFunction.CountA(.Range("G" & r & ":I" & r)) > 0 Then y = 1
            With desWS
                .Cells(.Rows.Count, "A").End(xlUp).Offset(1).Resize(x + y).Value = (arr(r, 1))
                .Cells(.Rows.Count, "B").End(xlUp).Offset(1).Resize(x + y).Value = (arr(r, 2))
                .Cells(.Rows.Count, "C").End(xlUp).Offset(1).Resize(x + y).Value = (arr(r, 3))
                For c = 4 To 6
                    If arr(r, c) <> "" Then
                        .Cells(.Rows.Count, "D").End(xlUp).Offset(1).Value = (arr(1, c))
                        .Cells(.Rows.Count, "E").End(xlUp).Offset(1).Value = (arr(r, c))
                    End If
                Next c
                If y > 0 Then
                    .Cells(.Rows.Count, "D").End(xlUp).Offset(1).Value = "Expense"
                    .Cells(.Rows.Count, "E").End(xlUp).Offset(1).Value = Join(Application.Transpose(Application.Transpose(srcWS.Range("G" & r & ":I" & r).SpecialCells(xlCellTypeConstants).Value)), "-")
                End If
                y = 0
            End With
        Next r
    End With
    Application.ScreenUpdating = True
End Sub
Thanks for the above VBA, it worked great.

I need to add some additional columns to the source data that will cause the VBA to change.

Columns 7-8, the header is "category" but also contains part of the "issue" and the data is also the "issue"
Columns 9-14, the "category" will all be "Expense" and the issue needs to be combined into "issue", there will be repeating column headers but with different data

Source data
DateIDNameConstructionITMarketingDSD - 1234 - WaterDSD - 2345 - VendingExpense PartExpense QtyExpense ReasonExpense PartExpense QtyExpense Reason
01/12/22​
1234​
Joe SmithMissing drywallMissing sign kit
2​
10001,Binders
1​
Missing10003,Paper
1​
Missing
01/25/22​
5678​
Jane DoeMissing monitorLabels
10​
02/02/22​
2468​
Mike SmithWiringPinpad broken
3​
5​
10007,Receipt tape
5​
Lost10008,Outlets
5​
Lost
02/15/22​
3692​
Linda JohnsonLabels10004,Pens
20​
Missing10003,Paper
20​
Missing

Formatted data
DateIDNameCategoryIssue
01/12/22​
1234​
Joe SmithConstructionMissing drywall
01/12/22​
1234​
Joe SmithMarketingMissing sign kit
01/12/22​
1234​
Joe SmithDSD1234 - Water - 2
01/12/22​
1234​
Joe SmithExpense10001,Binders - 1 - Missing
01/12/22​
1234​
Joe SmithExpense10003,Paper - 1 - Missing
01/25/22​
5678​
Jane DoeITMissing monitor
01/25/22​
5678​
Jane DoeMarketingLabels
01/25/22​
5678​
Jane DoeDSD2345 - Vending - 10
02/02/22​
2468​
Mike SmithConstructionWiring
02/02/22​
2468​
Mike SmithITPinpad broken
02/02/22​
2468​
Mike SmithDSD1234 - Water - 3
02/02/22​
2468​
Mike SmithDSD2345 - Vending - 5
02/02/22​
2468​
Mike SmithExpense10007,Receipt tap - 5 - Lost
02/02/22​
2468​
Mike SmithExpense10008,Outlets - 5 - Lost
02/15/22​
3692​
Linda JohnsonMarketingLabels
02/15/22​
3692​
Linda JohnsonExpense10004,Pens - 20 - Missing
02/15/22​
3692​
Linda JohnsonExpense10003,Paper - 20 - Missing
 
Upvote 0
@jdean5800
Forum members agree to help on a volunteer basis. The Forum does have a consultation service for a fee if that is the route you want to take. This is the link: Consulting Services
 
Upvote 0
Try:
VBA Code:
Sub FormatData()
    Application.ScreenUpdating = False
    Dim desWS As Worksheet, srcWS As Worksheet, r As Long, c As Long, x As Long, y As Long, z As Long, arr As Variant
    Set srcWS = Sheets("Sheet1")
    Set desWS = Sheets("Sheet2")
    desWS.UsedRange.ClearContents
    desWS.Range("A1:E1") = Array("Date", "ID", "Name", "Category", "Issue")
    With srcWS
        arr = .Range("A1", .Range("A" & .Rows.Count).End(xlUp)).Resize(, 14).Value
        For r = 2 To UBound(arr)
            x = WorksheetFunction.CountA(.Range("D" & r & ":H" & r))
            If WorksheetFunction.CountA(.Range("I" & r & ":K" & r)) > 0 Then y = 1
            If WorksheetFunction.CountA(.Range("L" & r & ":N" & r)) > 0 Then z = 1
            With desWS
                .Cells(.Rows.Count, "A").End(xlUp).Offset(1).Resize(x + y + z).Value = (arr(r, 1))
                .Cells(.Rows.Count, "B").End(xlUp).Offset(1).Resize(x + y + z).Value = (arr(r, 2))
                .Cells(.Rows.Count, "C").End(xlUp).Offset(1).Resize(x + y + z).Value = (arr(r, 3))
                For c = 4 To 6
                    If arr(r, c) <> "" Then
                        .Cells(.Rows.Count, "D").End(xlUp).Offset(1).Value = (arr(1, c))
                        .Cells(.Rows.Count, "E").End(xlUp).Offset(1).Value = (arr(r, c))
                    End If
                Next c
                For c = 7 To 8
                    If arr(r, c) <> "" Then
                        .Cells(.Rows.Count, "D").End(xlUp).Offset(1).Value = "DSD"
                        .Cells(.Rows.Count, "E").End(xlUp).Offset(1).Value = Mid(arr(1, c), 7, 9999) & " - " & arr(r, c)
                    End If
                Next c
                If y > 0 Then
                    .Cells(.Rows.Count, "D").End(xlUp).Offset(1).Value = "Expense"
                    .Cells(.Rows.Count, "E").End(xlUp).Offset(1).Value = Join(Application.Transpose(Application.Transpose(srcWS.Range("I" & r & ":K" & r).SpecialCells(xlCellTypeConstants).Value)), " - ")
                End If
                If z > 0 Then
                    .Cells(.Rows.Count, "D").End(xlUp).Offset(1).Value = "Expense"
                    .Cells(.Rows.Count, "E").End(xlUp).Offset(1).Value = Join(Application.Transpose(Application.Transpose(srcWS.Range("L" & r & ":N" & r).SpecialCells(xlCellTypeConstants).Value)), " - ")
                End If
                y = 0
                z = 0
            End With
        Next r
    End With
    Application.ScreenUpdating = True
End Sub
 
Upvote 0

Forum statistics

Threads
1,214,806
Messages
6,121,667
Members
449,045
Latest member
Marcus05

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