【问题标题】:Sum columns in excel using VB使用VB对excel中的列求和
【发布时间】:2014-09-05 23:55:07
【问题描述】:

好的,我在 excel 中有一个直截了当的二维数据块:第 1 行和第 1 列是标签,其余的是数字。我现在的任务是将每列的总和放在下面的第一个空单元格(行)中。

虽然我的练习数据集具有已知的维度,但我将使用此程序的实际数据集将具有可变数量的行和列。为此,我不能只说“=SUM(B2:B20)”,因为最后填充的单元格并不总是 B20(例如)。我想,对每一列求和的最简单方法是 FOR..NEXT 循环,但我就是无法让 VS 接受求和公式。到目前为止,这是我所得到的:

  `With xlWsheet2 'check for last filled row and column of transposed data'
        If xlApp.WorksheetFunction.CountA(.Cells) <> 0 Then
            lRow2 = .Cells.Find(What:="*",
                               After:=.Cells(1, 1),
                               LookAt:=Excel.XlLookAt.xlPart,
                               LookIn:=Excel.XlFindLookIn.xlFormulas,
                               SearchOrder:=Excel.XlSearchOrder.xlByRows,
                               SearchDirection:=Excel.XlSearchDirection.xlPrevious,
                               MatchCase:=False).Row
        Else : lRow2 = 1
        End If

        If xlApp.WorksheetFunction.CountA(.Cells) <> 0 Then
            lCol2 = .Cells.Find(What:="*",
                               After:=.Range("A1"),
                               LookAt:=Excel.XlLookAt.xlPart,
                               LookIn:=Excel.XlFindLookIn.xlFormulas,
                               SearchOrder:=Excel.XlSearchOrder.xlByRows,
                               SearchDirection:=Excel.XlSearchDirection.xlPrevious,
                               MatchCase:=False).Column
        Else : lCol2 = 1
        End If


        lastcell2 = xlWsheet2.Cells(lRow2, lCol2) 'defines last row, column of transposed data'
        emptyRow1 = xlWsheet2.Rows(lRow2).Offset(1) 'defines the first empty row'


        'add in cell of SUM underneath each column'
        For i As Integer = 2 To lCol2
            colTop = xlWsheet2.Cells(2, i)
            colBot = xlWsheet2.Cells(lRow2, i)

            ELtotal = xlWsheet2.Range(emptyRow1, i)
            ELtotal = .Sum(.Range(colTop, colBot))
        Next i
    End With

` 现在,ELtotal 语句曾经是一长串,但我试图查看 VS 的哪一部分有问题。它在第一个 .Range(emptyRow1, i) 处中断。这是我尝试过的该等式的其他迭代,但未被接受:

.Range(emptyRow1, I).Formula = "=SUM(colTop, colBot)"
.Range(emptyRow1, I).Formula = "=SUM(.cells(2,i), (lRow2,i))"
.Range(emptyRow1, I).Formula = .sum(.range(colTop, colBot)
.Range(emptyRow1, I).Value = etc...

无限可能

PS- 我对此很陌生,所以我可能以错误的方式处理整个过程......

【问题讨论】:

  • 是否可以假设任何包含数据(数字)的行都将被标记(在第 1 行),并且任何包含数据的列都将被标记?所有列是否包含相同数量的数据单元格,或者某些列是否包含比其他列更多的数据单元格?如果后者的答案是否定的,那么总和在“第一个”空单元格而不是“一个”空单元格中的必要性有多大?
  • @Clif,是的,所有行和列的长度都相同(数据量相同)。那些没有数字的单元格将有零。
  • 此外,所有列和行都将有一个标签(整个 A 列和第 1 行)。我曾考虑将整个数据集放入一个 3d 数组中,但由于数据被吐出到 excel 中,我想我会先尝试这种方式。

标签: vb.net excel sum


【解决方案1】:

根据你告诉我的关于行和列标题的内容,我相信这段代码会做你想做的,即在下面的第一个空单元格中放置一个单列总和。

Sub find()   
 Dim lastrow As Long, lastcol As Long, thiscol As Long

    lastrow = Cells(Rows.Count, 1).End(xlUp).Row
    lastcol = Cells(1, Columns.Count).End(xlToLeft).Column
    For thiscol = 2 To lastcol
        Cells(lastrow + 1, thiscol).Select
        ActiveCell.Value = WorksheetFunction.Sum(Range(Cells(1, ActiveCell.Column), ActiveCell))
    Next
    End Sub

祝你好运。

【讨论】:

  • 感谢 Clif,似乎这是一个更好的方法,但是我整个早上都在追查错误。目前,VS 已接受语法,但我在第三行收到“对象变量或未设置块变量”消息,其中 'lastrow = Cells(Rows.Count .....' 我尝试更改变量类型lastrow 到 excel.Range,但是循环中的 'lastrow + 1' 表达式无效 bc (+) 显然不能在范围内使用。Grrr!
  • 很抱歉听到代码不起作用。我使用 Excel 2010 和一个非常简单的数据集对其进行了测试,我将字母“a”放在单元格 A1:A5 中。然后我将字母 b、c、d 分别放在单元格 B1、C1 和 D1 中,并用数字填充单元格 B2:D5。想到的一件事是,作为长数据类型的“lastrow”将被限制为
  • 超过 200 万行?嘘,我希望不会!它通常在 25 到 35 行之间,列数大致相同。我将尝试一个与您所做的类似的简单设置,看看会发生什么。
  • 看起来 Rows 和 ActiveCell 被标记为未声明。不知道我必须申报这些...?
  • 所以即使使用我描述的设置,代码也无法为您工作?我很困惑为什么会这样,因为它在这方面起作用。在这一点上,我最好的想法是发布一个新问题,询问其他人是否可以提供帮助,也许这里有一些编码人员遇到了类似的情况/错误并有解决方案。再次对这些问题表示歉意。
【解决方案2】:

在这种情况下,此公式将完成对两列 A 和 B 求和的技巧:

= sum($A:$B)

如果标题可能被解释为可能对总和有贡献的数值,则应将公式修改为

= sum($A:$B) - sum($A$1:$B$1)

【讨论】:

  • 我不想把列加在一起,而是想把每一列加起来。
  • @BG-:嗯,这是我发布的答案的一个非常简单的简化。
  • 那么我可以输入 '= sum($A:$A)' 来获得列的总数吗?
【解决方案3】:

为了将 DataGridView 中所有数字列的总和导出到 Excel,请在表单中添加一个按钮并在其单击事件中添加以下代码:-

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
    '--- Export to Excel -------------------------------------------------
    Dim xlApp As Excel.Application
    Dim xlWorkBook As Excel.Workbook
    Dim xlWorkSheet As Excel.Worksheet
    Dim misValue As Object = System.Reflection.Missing.Value
    Dim i As Integer
    Dim j As Integer
    Dim datarange As Excel.Range

    Dim save_file As New SaveFileDialog
    'give its extension
    ''save_file.Filter = "xls files (*.xls)|*.xls|All files (*.*)|*.*"
    'save_file.Filter = "xls files (*.xls)|*.xls"
    save_file.Filter = "xls files (*.xls)|*.xls|Excel 2007|*.xlsx"
    ''Select xls
    save_file.FilterIndex = 2
    save_file.FileName = "My_excel_report_"
    save_file.RestoreDirectory = True

    Try
        If save_file.ShowDialog() = DialogResult.OK Then
            xlApp = New Excel.ApplicationClass
            xlWorkBook = xlApp.Workbooks.Add(misValue)
            xlWorkSheet = xlWorkBook.Sheets("sheet1")

            For x = 0 To DataGridViewSummary1.ColumnCount - 1
                xlWorkSheet.Cells(0 + 1, x + 1) = _
                DataGridViewSummary1.Columns(x).HeaderText
            Next

            For i = 0 To DataGridViewSummary1.RowCount - 1
                For j = 0 To DataGridViewSummary1.ColumnCount - 1
                    If IsDate(DataGridViewSummary1(j, i).Value) Then
                        'MsgBox("The cell value is date")
                        xlWorkSheet.Cells(i + 2, j + 1) = FormatDateTime(CDate(DataGridViewSummary1(j, i).Value.ToString), DateFormat.ShortDate)
                        xlWorkSheet.Cells(i + 2, j + 1).HorizontalAlignment = Excel.Constants.xlCenter
                        xlWorkSheet.Cells(i + 2, j + 1).VerticalAlignment = Excel.Constants.xlCenter
                    Else
                        xlWorkSheet.Cells(i + 2, j + 1) = _
                            DataGridViewSummary1(j, i).Value.ToString()
                    End If
                Next
            Next

            datarange = xlWorkBook.ActiveSheet.UsedRange
            datarange.Font.Name = "Consolas"
            datarange.Font.Size = 10
            '--- added on 07/09/2016 -------------------------------------------------------------------
            Dim lastrow, lastcol As Long
            With xlWorkSheet
                lastcol = .Cells(1, .Columns.Count).End(Excel.XlDirection.xlToLeft).Column
                lastrow = .Range("A" & .Rows.Count).End(Excel.XlDirection.xlUp).Row
            End With
            'MessageBox.Show("The last column in Sheet1 which has data is " & lastcol)
            'MessageBox.Show("The last row in Col A of Sheet1 which has data is " & lastrow)

            For i = 2 To lastcol
                If IsNumeric(xlWorkSheet.Cells(lastrow, i).Value) Then
                    xlWorkSheet.Cells(lastrow + 1, i).Select()
                    xlWorkSheet.Cells(lastrow + 1, i).Value = xlApp.WorksheetFunction.Sum(xlWorkSheet.Range(xlWorkSheet.Cells(1, i), xlWorkSheet.Cells(lastrow + 1, i)))
                End If
            Next i
            xlWorkSheet.Columns.AutoFit()
            '----------------------------------------------------------------------------------------------
            xlWorkSheet.SaveAs(save_file.FileName)  'sd.filename reurns save file dialog path
            xlWorkBook.Close()
            xlApp.Quit()
            releaseObject(xlApp)
            releaseObject(xlWorkBook)
            releaseObject(xlWorkSheet)
             '--------------------------------------

            Dim proc As Process = Nothing
            Dim startInfo As New ProcessStartInfo
            startInfo.FileName = "EXCEL.EXE"
            startInfo.Arguments = save_file.FileName
            Process.Start(startInfo)
        End If
            Catch ex As Exception
        MessageBox.Show(ex.ToString)
        'GlobalErrorHandler(ex)
    End Try
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多