简体   繁体   中英

Excel report - formulas VBA

I'm having a little difficulty with something on my report that I'm building in VB6. Bascially I'm building a dynamic report where the Headings, and 2 columns (clients, students) get populated from a recordset. As you can see in the picture, at the end of my headings, I added a TOTAL heading with clients and students below. I'm trying to take a total of all clients in each of the columns and have it be summed up under TOTAL, same with students. The number of columns (UCLA, SDU, SCCU) might vary, so I'm trying to make it dynamic.Basically start with total for A, then B, then C, D and NONE. Any ideas? 在此处输入图片说明 EDIT: I select the SHORT LABEL from SQL SERVER and populate until g_RS3 is empty

Do While Not g_RS3.EOF
    With xlSheet.Cells(xlRow, xlCol)
        .Value = g_RS3("ShortLabel")
            .Offset(1, 0).Value = " Clients "
            .Offset(1, 1).Value = " Students"
                With .Offset(1, 0)
                    .Font.Bold = True
                .Borders.Weight = xlThin
            End With
            With .Offset(1, 1)
                .Font.Bold = True
                .Borders.Weight = xlThin
            End With
            With .Resize(1, 2)
                .Font.Bold = True
                .WrapText = True
                .VerticalAlignment = xlCenter
                .Merge
                .HorizontalAlignment = xlCenter
                .Borders.Weight = xlThin
            End With
    End With
    xlCol = xlCol + 2
    g_RS3.MoveNext
Loop
With xlSheet.Cells(xlRow, xlCol)
    .Value = "TOTAL"
        .Offset(1, 0).Value = "Clients"
        .Offset(1, 1).Value = "Students"
            With .Offset(1, 0)
                .Font.Bold = True
            .Borders.Weight = xlThin
        End With
        With .Offset(1, 1)
            .Font.Bold = True
            .Borders.Weight = xlThin
        End With
        With .Resize(1, 2)
            .Font.Bold = True
            .WrapText = True
            .VerticalAlignment = xlCenter
            .Merge
            .HorizontalAlignment = xlCenter
            .Borders.Weight = xlThin
        End With
End With

Then I start in xlrow = 4 xlcol = 2 and populate the CLIENT AND STUDENT columns with data. The loops I have are quite long. But the user will only view the extract. What they do with it once its generated is up to them. The application gives them an option of adding a SHORTLABEL, which needs to be displayed in the extract once they generate it.

Either the SUMIF function or SUMIFS function can perform this handily.

In H4 as a standard formula,

=sumifs($b4:$g4, $b$3:$g$3, h$3)

Fill both right and down.

In VBA as,

with worksheets("Sheet1")
    .range("H4:I8").formula = "=sumifs($b4:$g4, $b$3:$g$3, h$3)"
    'optional revert to values only
    '.range("H4:I8") = .range("H4:I8").values
end with

You will have to determine the extents of the clients/students ranges but half of that is done simply knowing where to put the formula (eg H4).

VBA

I've removed a lot of the redundancy that your original code used. Given that you are not yet populating data into the client/student columns, I've used a method where a Total column(s) is always written to the right complete with formulas. If there is another row set, that Totals will be overwritten and a new one created to the right.

Dim xlStartCol As Long
xlStartCol = xlCol
Do While Not g_RS3.EOF
    With xlSheet.Cells(xlRow, xlCol)
        .Resize(1, 2).Merge
        .Value = "TEST" 'g_RS3("ShortLabel")
        .Offset(1, 0).Resize(1, 2) = Array("Clients", "Students")
        .Offset(2, 0).Resize(1, 2).ClearContents
        With .Offset(0, 1)
            .Resize(1, 2).Merge
            .Value = "Total"   'keep writing Total to the right; it will be overwritten if there is another ShortLabel
            .Offset(1, 0).Resize(1, 2) = Array("Clients", "Students")
            .Offset(2, 0).Resize(1, 2).Formula = _
                "=SUMIFS(" & Range(.Parent.Cells(xlRow + 2, xlStartCol), .Parent.Cells(xlRow + 2, xlCol + 1)).Address(0, 1) & Chr(44) & _
                             Range(.Parent.Cells(xlRow + 1, xlStartCol), .Parent.Cells(xlRow + 1, xlCol + 1)).Address(1, 1) & Chr(44) & _
                             .Parent.Cells(xlRow + 1, xlCol - 1).Address(1, 0) & Chr(41)
        End With
        With .Resize(2, 4)
            .Font.Bold = True
            .VerticalAlignment = xlCenter
            .HorizontalAlignment = xlCenter
            .Borders.Weight = xlThin
        End With
    End With
    xlCol = xlCol + 2
    g_RS3.MoveNext
Loop

Once you have actually populated the data into each pair of columns and know the extents, simply use the Range.FillDown method to populate the remaining formulas.

xlCol

I would recommend removing portions of recorded code that are not relevant. Recorded code is very verbose and hampers readability. You might also want to look into the For XML method of creating a query in T-SQL. This will expand the columns returned and allow you to use a fields count to determine the extents.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM