0

我在同一个excel工作簿中有两个excelsheets Sheet1和Sheet2。在 sheet1 中,我有以下数据,如图片 1 所示。 图片1 我只想将 A 列、B 列和总计复制到 sheet2。在 VBA 中,我使用了这段代码。它工作正常,但是当我将它转换为 VB.Net 时出现问题

Sub VBA()
    Sheets("Sheet1").Select
    Range("A2:B4").Select
    Range(Selection, Selection.End(xlDown)).Select
    Selection.Copy
    Sheets("Sheet2").Select
    Range("A2").Select
    ActiveSheet.Paste
    Sheets("Sheet1").Select
    Range("A2").Select
    Selection.End(xlToRight).Select
    Range(Selection, Selection.End(xlDown)).Select
    Selection.Copy
    Sheets("Sheet2").Select
    Range("C2").Select
    ActiveSheet.Paste
End Sub

在 VB.Net 中,我使用此代码将数据从 sheet1 复制到 sheet2。

Private Sub Button1_Click
    Dim xlApp As New Excel.Application
    Dim xlwb As Excel.Workbook
    Dim xlsheet, xlsheet2 As Excel.Worksheet
    Dim lCol As Long = 0
    Dim xlsourceRange, xlDestRange As Excel.Range
    with xlApp
    .visible = True
    xlwb = .workbooks.open("D:\test.xlsx")
    xlsheet = xlwb.Sheets("Sheet1")
    xlsheet2 = xlwb.Sheets("Sheet2")
    xlSourceRange = xlSheet.Range("A2:B2000")'This is copies Column A and Column B
    xlDestRange = xlsheet2.Range("A2")
    xlSourceRange.Copy(xlDestRange)

    End with
    End Sub
    End Class

真正的问题是复制第一列中的总数,如图1所示。我无法将其复制到 sheet2,因为数据在 sheet1 中未固定,它是向右递增的。我的意思是在目前的情况下,我从 c 列到 H 列有六个客户,总数在 I 列中。但是如果再增加两个客户,则 Total 列从 I 列移动到 K 列。这方面的任何帮助都非常有用.

Manny 感谢来自 MSDN 的 Kevin 抽出时间来回答这个问题。来自肯文。开始注意,事情并不像下面解释的那么简单。

好的,从您提供的文件中,我认为获得总数(不确定您想要列中的哪一个)或只是最后一个(13,886)会很简单。使用自动化最后一列失败,因为根据 Excel,S 列是最后一列,Excel 的最后一行报告是 2628。长话短说,我使用下面的第一个 SQL 语句(SELECT TOP * 8),将这些值递增为基于1。如果最后一部分有效,那么我会选择总列没有空单元格值的数据,这当然会删除 Total 上方的行,所以稍后我会处理这个问题。在读取总列中的单元格值时,我将带有负值的单元格视为字符串并将它们转换为罕见的负值,然后将它们存储为字符串,因为我们无法将常规文本值与数值一起获取(但您可以将我的逻辑调整为这样做)。任何方式到底一个 DataTable 都有两列我们关心的行索引和值。使用行索引和值,您可以获得列总计和行总计。

我没有做的是实际复制到另一张纸上。最后,当看到这样的数据时,期望是在找到实际的最后一行/列以及混合数据时,我几乎知道会有相当多的代码。

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Dim dt As New DataTable
        Dim Builder As New OleDb.OleDbConnectionStringBuilder With
            {
                .DataSource = IO.Path.Combine(Application.StartupPath, "WS_1.xlsx"),
                .Provider = "Microsoft.ACE.OLEDB.12.0"
            }
        Builder.Add("Extended Properties", "Excel 12.0;IMEX=1;HDR=No;")
        Using cn As New OleDb.OleDbConnection With {.ConnectionString = Builder.ConnectionString}
            Using cmd As New OleDb.OleDbCommand With
                {
                    .Connection = cn,
                    .CommandText = "SELECT Top 8 * FROM [Customer$]"
                }
                cn.Open()
                dt.Load(cmd.ExecuteReader)
                Dim FoundRow As Int32 = -1
                Dim FoundCol As Int32 = -1
                For Row As Integer = 0 To dt.Rows.Count - 1
                    For Col As Int32 = 0 To dt.Columns.Count - 1
                        If dt.Rows(Row).Item(Col).ToString = "Total" Then
                            FoundRow = Row + 1
                            FoundCol = Col + 1
                        End If
                    Next
                Next
                If FoundRow > -1 Then
                    dt = New DataTable
                    cmd.CommandText = <SQL>SELECT F<%= FoundCol %> FROM [Customer$]  WHERE Not IsNull(F<%= FoundCol %>) </SQL>.Value
                    dt.Load(cmd.ExecuteReader)
                    Dim NewTable As New DataTable With {.TableName = "MyTable"}
                    NewTable.Columns.Add(New DataColumn With {.ColumnName = "Identifier", .DataType = GetType(Int32), .AutoIncrement = True, .AutoIncrementSeed = 1})
                    NewTable.Columns.Add(New DataColumn With {.ColumnName = "RowIndex", .DataType = GetType(Int32)})
                    NewTable.Columns.Add(New DataColumn With {.ColumnName = "Value", .DataType = GetType(String)})
                    For Each row As DataRow In dt.Rows
                        Dim Temp As String = row.Item(0).ToString.TrimStart
                        If Temp.StartsWith("(") Then
                            Temp = System.Text.RegularExpressions.Regex.Replace(Temp, "[)(,]", "")
                            Dim Value As Int32 = 0
                            If Int32.TryParse(Temp, Value) Then
                                Value = Value * -1
                                Console.WriteLine(Value)
                                NewTable.Rows.Add(New Object() {Nothing, Nothing, Value.ToString})
                            Else
                                NewTable.Rows.Add(New Object() {Nothing, Nothing, Value.ToString})
                            End If
                        Else
                            NewTable.Rows.Add(New Object() {Nothing, Nothing, Temp})
                        End If
                    Next
                    Dim xrow As DataRow
                    For i As Int32 = 1 To FoundRow - 1
                        xrow = NewTable.NewRow
                        NewTable.Rows.InsertAt(xrow, 0)
                    Next
                    For i As Int32 = 0 To NewTable.Rows.Count - 1
                        NewTable.Rows(i).SetField(Of Int32)("RowIndex", i)
                    Next
                    Console.WriteLine()
                Else
                    Console.WriteLine("Did not find a column with Total.")
                End If
            End Using
        End Using
    End Sub

代码模块。

Module ExcelExtensions
    ''' <summary>
    ''' Will be used in next article I wrote
    ''' </summary>
    ''' <param name="Index"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.Runtime.CompilerServices.Extension()> _
    Public Function ExcelColumnName(ByVal Index As Integer) As String
        Dim chars = New Char() _
            {
                "A"c, "B"c, "C"c, "D"c, "E"c, "F"c, "G"c, "H"c, "I"c,
                "J"c, "K"c, "L"c, "M"c, "N"c, "O"c, "P"c, "Q"c, "R"c,
                "S"c, "T"c, "U"c, "V"c, "W"c, "X"c, "Y"c, "Z"c
            }
        Index -= 1
        Dim columnName As String
        Dim quotient = Index \ 26
        If quotient > 0 Then
            columnName = ExcelColumnName(quotient) + chars(Index Mod 26)
        Else
            columnName = chars(Index Mod 26).ToString()
        End If
        Return columnName
    End Function
End Module
4

1 回答 1

0

这是获得 C 到 ? 列总数的一种方法 在哪里 ?表示可以不时更改的未指定列。如果将此公式插入单元格 G3,它将返回单元格 C3:F3 的总和。或者如果你把它放到 R7 中,它会给你 C7:Q7 的总和。

rg.Formula = "=SUM(INDIRECT(ADDRESS(ROW(),3)&"":""&ADDRESS(ROW(),COLUMN()-1)))"
于 2013-08-29T22:04:15.477 回答