2013-07-23 2 views
0

У меня есть два листа Excel1 и Sheet2, оба в одной и той же книге excel. В листе 1 у меня есть следующие данные, как на рисунке 1. Picture 1 Я просто хочу скопировать столбец A, columnB и общее число, на sheet2. В VBA Я использовал этот code.Which работает нормально, но проблема возникает, когда я преобразовать это VB.NetКак найти последний столбец в Excel и копировать в 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 на Лист2.

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 

Настоящая проблема заключается в том, чтобы скопировать общее количество, которое находится в колонке I, как в picture1. Я не могу скопировать его в sheet2, потому что данные не фиксированы в листе1, он пошагово к праву. Я имею в виду, что в нынешнем сенарио у меня шесть клиентов из столбца c в H, а общее число находится в столбце I. Но если есть еще два клиента, столбец Total перемещается из столбца I в столбец K. Любая помощь в этом действительно определяется ,

Мэнни Благодаря Кевину из MSDN, чтобы найти время, чтобы ответить на этот вопрос. От Kenvin. Начните с записи, все было не так просто, как описано ниже.

Хорошо, из представленного вами файла я думал, что было бы просто получить итоговые данные (не уверен, какой из них вы хотели бы в колонке) или просто последний (13,886). Не удалось использовать последний столбец автоматизации, потому что столбец S является последним столбцом в Excel, а последний отчет по Excel - 2628. Короче говоря, я использовал предположение, чтобы получить последнюю строку/столбец, используя первый оператор SQL ниже (SELECT TOP * 8), увеличьте эти значения на один. Если последняя часть работала, я затем выбираю данные, в которых общий столбец не имеет пустых значений ячеек, которые, конечно, удаляют строки выше Total, поэтому позже я позабочусь об этом. При чтении значений ячейки в общем столбце я беру ячейки с отрицательными значениями, которые рассматриваются как строки и преобразуют их в редкие отрицательные значения, затем сохраняют их как строки, поскольку мы не можем получать регулярные текстовые значения вместе с числовыми значениями (но вы можете настроить мою логику на Сделай так). В любом случае, в конце DataTable имеет два столбца, нас интересует индекс строки и значение. Используя индекс и значение Row, вы получаете итоговые суммы столбцов и общую сумму строк.

То, что я не делал, является фактической копией на другой лист. Наконец, когда вы видите такие данные, ожидание заключается в том, чтобы найти то, что было в последней строке/столбце, и смесь данных, которые я в значительной степени знал, что будет достаточный объем кода.

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 

ответ

0

Это один из способов получить общее количество для столбцов C? где ? означает неуказанный столбец, который может время от времени меняться. Если вы вставляете эту формулу в ячейку G3, она возвращает сумму ячеек C3: F3. Или, если вы поместите его в R7, он даст вам сумму C7: Q7.

rg.Formula = "=SUM(INDIRECT(ADDRESS(ROW(),3)&"":""&ADDRESS(ROW(),COLUMN()-1)))" 
+0

Исходный столбец не фиксирован. Но столбец назначения исправлен. Я пытаюсь получить последний столбец, который является итогом от столбца sheet1 to sheet2 C. –

+0

Итак, вы хотите скопировать и вставить в качестве значений? RangeSource.Copy> RangeDest.PasteSpecial ... –

Смежные вопросы