【问题标题】:Setting Subtotals to the bottom of an Excel table in VBA from MS Access从 MS Access 将小计设置为 VBA 中 Excel 表格的底部
【发布时间】:2018-07-15 02:18:41
【问题描述】:

我有一个简单的 MS Access 查询,我将其输出到 Excel。我只想将总计添加到表格外部的底部,这样如果用户过滤表格,他们就可以看到小计,所以我使用的是小计(109,[MyField])。

我暂时打开了 Excel 对象模型,所以我可以看到智能感知,因为我在 Excel 中设置确定表格底部的范围时不断出错。一切正常,除了底部。我将在 Excel 对象模型工作时关闭它。很抱歉,我忘记了声明“作为对象”而不是直接引用示例的术语:xlApp 为 Excel.Application。

Public Sub ShowAllTotals()
    Dim xlApp As excel.Application ' Object
    Dim WB As excel.Workbook 'Object
    Dim xlSheet As excel.Worksheet ' Object
    Dim qdf As DAO.QueryDef
    Dim strLocation As String
    Dim rs As DAO.Recordset
    Dim x, M, i As Integer
    Dim fld As Variant
    Dim rng As Object, TBL As Object, xlBottom As Object
    Dim strSQL As String
    Dim iCols(3 To 10) As Integer
    Dim intRecords As Integer, intTotals As Integer, intCOL As Integer

    strSQL = "SELECT COB_ID, BL AS [COB TITLE], ANNUAL AS CONTROL, ALLOCATION, SP_C, SP_O, COMMITS, OBS, EXPN, OBS_SP_RATE, RA AS AVAILABLE " _
           & "FROM TOTALS_COB_ALL;"

    Debug.Print strSQL
    Set xlApp = CreateObject("Excel.Application")
    xlApp.Visible = False
    Set xlSheet = xlApp.Workbooks.Add().Sheets(1)
    Set rs = CurrentDb.OpenRecordset(strSQL)
    With xlSheet.Rows("2:" & xlSheet.Rows.Count).Interior
        .Pattern = xlNone
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With

    With xlSheet.Rows("2:" & xlSheet.Rows.Count).Font
        .Name = "Calibri"
        .FontStyle = "Regular"
        .Size = 11
        .ThemeColor = xlThemeColorLight1
        .TintAndShade = 0
        .ThemeFont = xlThemeFontMinor
    End With

    'PLACE
    intCOL = 1

    For Each fld In rs.Fields
        xlSheet.Cells(1, intCOL).Value = fld.Name
        intCOL = intCOL + 1
    Next

    With xlSheet
        .Range("A2").CopyFromRecordset rs
        .Columns("C:I").NumberFormat = "$#,##0.00"
        .Columns("J").NumberFormat = "0.00%"
        .Columns("K").NumberFormat = "$#,##0.00"
        .Cells.EntireColumn.AutoFit
    End With

    'Format the Table in Excel
    Set rng = xlSheet.Range(xlSheet.Range("A1"), xlSheet.Range("A1").SpecialCells(xlLastCell))
    Set TBL = xlSheet.ListObjects.Add(xlSrcRange, rng, , xlYes)
    TBL.TableStyle = "TableStyleMedium2"
    xlSheet.Cells.EntireColumn.AutoFit

    'ADD TOTALS ATTEMPT

    intRecords = rs.RecordCount
    Dim strRange As String
    strRange = "C" & intRecords + 2
    Set xlBottom = xlSheet.Range(strRange)
    With xlSheet
        .Range("C79").Offset(0, 3).FormulaR1C1 = "=SUBTOTAL(109, [CONTROL])"
        'Range(xlBottom.Offset(0, 3).Address).FormulaR1C1 = "=SUBTOTAL(109,[CONTROL])" 'CONTROL
        '.Offset(0, 4).Address.FormulaR1C1 = "=SUBTOTAL(109,[ALLOCATION])" 'ALLOCATION
        '.Offset(0, 5).Address.FormulaR1C1 = "=SUBTOTAL(109,[SP_C])" 'SP_C
        '.Offset(0, 6).Address.FormulaR1C1 = "=SUBTOTAL(109,[SP_O])" 'SP_O
        '.Offset(0, 7).Address.FormulaR1C1 = "=SUBTOTAL(109,[COMMITS])" 'COMMITS
        '.Offset(0, 8).Address.FormulaR1C1 = "=SUBTOTAL(109,[OBS])" 'OBS
        '.Offset(0, 9).Address.FormulaR1C1 = "=SUBTOTAL(109,[EXPN])" 'EXPN
        '.Offset(0, 11).Address.FormulaR1C1 = "=SUBTOTAL(109,[AVAILABLE])" 'AVAILABLE
    End With

    'cleanup
    Set xlSheet = Nothing
    xlApp.Visible = True
    Set rs = Nothing
    Set rng = Nothing
    Set TBL = Nothing
    Set xlBottom = Nothing
End Sub

【问题讨论】:

  • 我还清理了你的代码。它仍然需要工作,但现在更具可读性。匈牙利符号也有助于变量命名约定。
  • 我愿意学习更好的变量表示法。谢谢你。你有什么建议?
  • 保持一致并命名描述它们用途的事物。 strSQL 是愚蠢的 IMO - 说它是一个字符串 b/c 毫无意义,它已经在上下文中暗示它是一个字符串。大多数时候它只是混淆了可读性,更不用说它类似于说金枪鱼之类的东西了。金枪鱼是一条鱼,我们为什么要说双语?另一个例子 - intRecords。为什么?在您的代码中的每一次出现时,它的数据类型都非常明显,无需这么说。
  • 知道了。当我想快速查看某些东西是否可行时,我经常将 strSQL 和 intRecords 用作虚拟模板构造函数。还要注意 strSQL 如何让我快速记住 Set rs = CurrentDB.OpenRecordset(strSQL) 而不必考虑太多。如果我在发布前不花额外的 5 分钟清理代码,你的反应是预料之中的。出于同样的原因,如果我的代码随时可以发布,那就更好了,所以感谢你在金枪鱼上叫我。

标签: excel vba ms-access


【解决方案1】:

我刚刚从最近开发的一份烦人的报告中抓取了一段简洁的代码。

'ws = worksheet object

 ws.Cells(ws.Rows.Count, _
Chr("Char Value of the column you wish to append your formula too")) _
.End(xlUp).Offset(2, 0).Formula = "=SUM(your range)"

显然您将不得不填写空白,但您可以轻松地从 excel 工作表函数或从 recordset.RecordCount 方法的简单 matjh 创建动态范围。

【讨论】:

  • 感谢您的提示。它帮助我完成了。
【解决方案2】:

这是基于您的帮助的最终工作代码。关于 SUBTOTAL,我确实必须将第一个参数更改为 9 而不是 109。我有一个问题是为什么我需要将第一个偏移量设置为 (1.0) 而其余的设置为 (0,0) 才能获得它们是在同一行吗?

'add Totals
'Its really strange.  Note how the offset for the first one is Offset(1,0)  and the rest are (0,0)
'If I don't do that, the rest will be 1 row lower


xlSheet.Cells(xlSheet.Rows.Count, Chr(99)).End(xlUp).Offset(1, 0).FormulaR1C1 = "=SUBTOTAL(9, R2C:R[-1]C)"   'C
xlSheet.Cells(xlSheet.Rows.Count, Chr(100)).End(xlUp).Offset(0, 0).FormulaR1C1 = "=SUBTOTAL(9, R2C:R[-1]C)"  'D
xlSheet.Cells(xlSheet.Rows.Count, Chr(101)).End(xlUp).Offset(0, 0).FormulaR1C1 = "=SUBTOTAL(9,R2C:R[-1]C)"   'E
xlSheet.Cells(xlSheet.Rows.Count, Chr(102)).End(xlUp).Offset(0, 0).FormulaR1C1 = "=SUBTOTAL(9,R2C:R[-1]C)"   'F
xlSheet.Cells(xlSheet.Rows.Count, Chr(103)).End(xlUp).Offset(0, 0).FormulaR1C1 = "=SUBTOTAL(9,R2C:R[-1]C)"   'G
xlSheet.Cells(xlSheet.Rows.Count, Chr(104)).End(xlUp).Offset(0, 0).FormulaR1C1 = "=SUBTOTAL(9,R2C:R[-1]C)"   'H
xlSheet.Cells(xlSheet.Rows.Count, Chr(105)).End(xlUp).Offset(0, 0).FormulaR1C1 = "=SUBTOTAL(9,R2C:R[-1]C)"   'I
xlSheet.Cells(xlSheet.Rows.Count, Chr(107)).End(xlUp).Offset(0, 0).FormulaR1C1 = "=SUBTOTAL(9,R2C:R[-1]C)"   'K

【讨论】:

  • Chr("Control") 不正确。 Chr 函数使用数字等值字符,即 a、b、c、+、/、*。
  • 所以控件可能是您的标题,但该列很可能仍标记为“a”
  • Chr(99) 或 Chr(67) 都给我一个运行时错误 1004 应用程序定义或对象定义错误。错误是否在这一边:.End(xlUp).Offset(2, 0).Formula = "=SUBTOTAL(109, [ALLOCATION])"
  • 我不知道小计功能,所以它可能是由于不同的对象模型。为什么不直接使用我们知道是 excel 函数的求和公式?
  • 因为如果用户过滤列表,对于列表中的几个项目,总数不会改变。当我使用小计时,我只能让它改变。自 2003 年以来也是如此。如果您转到要总计的列的底部并按住 alt+ ,您将得到 SUBTOTAL(109, [Your column Name])
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多