Нужно выбрать неопределенное количество строк в Excel как часть более крупного макроса VBA - PullRequest
4 голосов
/ 06 декабря 2011

Я работаю с книгой Excel, содержащей большое количество листов;первый лист связан с внешней программой и извлекает данные через внешнюю функцию, а число импортируемых строк значительно варьируется.

Данные этого блока распространяются по ряду последующих листов.Первым шагом было заполнение столбца A (имя строки) количеством строк в листе 1. Отсюда данные разбиты на несколько столбцов (в настоящее время B-> L).В верхней строке используется функция IF () для заполнения первой строки, и я хочу написать чистый макрос, чтобы скопировать эту формулу в строку x (которая зависит от каждого обновления импорта данных), а затем вставить значения для управляемого размера файла..

Вот что у меня так далеко;это работает, но это довольно (читай: ОЧЕНЬ!) неуклюжий:

Sub Refresh_Data()  
    Sheets("Sheet2").Select  
    ActiveWindow.ScrollWorkbookTabs Sheets:=13  
    Sheets(Array("Sheet2" ... "Sheet25")).Select     
    Sheets("Sheet2").Activate  
    Sheets("Sheet25").Select Replace:=False  
    Range("B1:L1").Select  
    Selection.Copy  
    Range("__B2:B1000__").Select  
    ActiveSheet.Paste  
    Application.Calculate  
    ActiveWindow.ScrollWorkbookTabs Position:=xlFirst  
    Sheets(Array("Sheet2" ... "Sheet25")).Select  
    Sheets("Sheet2").Activate  
    Sheets("Sheet25").Select Replace:=False  
    Sheets("Sheet2").Select  
    Range("B3").Select  
    Sheets(Array("Sheet2" ... "Sheet25")).Select  
    Sheets("Sheet2").Activate  
    Sheets("Sheet25").Select Replace:=False  
    Range("B3:L4").Select  
    Range("__B2:L1000__").Select  
    Application.CutCopyMode = False  
    Selection.Copy  
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _  
        :=False, Transpose:=False  
    Sheets("Check_sheet").Select  
    MsgBox "Update complete"  
End Sub`

Главное, чего я хочу добиться, это заменить код B2:L1000 чем-то, что можетоцените количество строк в столбце A и соответственно выберите диапазон в строках от B до L.

Поскольку столбец L является последним заполненным столбцом, я не понимаю, почему это также нельзя сделать горизонтально, а неопределение "B: L", если необходимо добавить будущие столбцы.

Ответы [ 2 ]

10 голосов
/ 06 декабря 2011

Хотя более ранний ответ имеет свои достоинства:

1) Я бы не использовал COUNTA, потому что если в строке или столбце есть пустые ячейки, ячейки внизу или справа будут игнорироваться.

2) Я бы никогда не стал полагаться на то, что пользователь выберет правильный лист для использования до запуска макроса;особенно один с таким большим количеством листов.

Моя реакция на этот вопрос заключается в том, что вы установили запись макроса, побродили по книге и остановили запись.Вы выбираете одну вещь, затем другую.Вы прокручиваете листы.Для меня большинство утверждений не являются неуклюжими, они бессмысленны.

Следующее включает в себя ответ на ваш вопрос о поиске последней строки столбца A, но это больше учебник по поиску измерений диапазона,вывести данные за пределы диапазона и затем поместить их в другое место.Похоже, это большая часть того, что вы пытаетесь сделать с минимальным пониманием VBA.Прошу прощения, если эта критика несправедлива, но именно такое впечатление производит ваш вопрос.

Sub Test()

  Dim RowS01Max As Integer
  Dim Sheet1Data() As Variant

  ' With Sheets("Sheet1") allows you to access data within worksheet Sheet1
  ' without selecting it.
  ' Range("A1:C11") refers to a range within the active sheet
  ' .Range("A1:C11") refers to a range within the sheet identified in the
  '         With statement.
  ' ^ Note the dot
  With Sheets("Sheet1")

    ' Rows.Count is the number of rows for the version of Excel you are using.
    ' .Cells(Rows.Count, "A") address the bottom row of column A of worksheet
    ' Sheet1.
    ' .Cells(Rows.Count, 1) refer to column A by number.
    ' End(xlUp) is the VBA equivalent of Ctrl+Up.
    ' If you positioned the cursor at the bottom of column A and pressed
    ' Ctrl+Up, the cursor would jump to the last row in column A with a value.
    ' The following statement gets that row number without actually moving
    ' the cursor.
    RowS01Max = .Cells(Rows.Count, "A").End(xlUp)

    ' The following statement loads the contents of range A1:C11 of
    ' Sheets("Sheet1") into array Sheet1Data.
    Sheet1Data = .Range("A1:C11").Value

    ' This is the same statement but the range is specified in a different way.
    ' .Cells(Row,Column) identifies a single cell within the sheet specified in
    ' the With statement.  .Cells(1,1) identifies row 1, column 1 which is A1.
    '. Cells(11, "C") identifies row 11, column C which is C11.
    Sheet1Data = .Range(.Cells(1, 1), .Cells(11, "C")).Value

    ' This statement uses RowS01Max to specify the last row
    Sheet1Data = .Range(.Cells(1, 1), .Cells(RowS01Max, 1)).Value

    ' In all three examples above, the contents of the specified range will
    ' be loaded to array Sheet1Data.  Whichever range you pick, Sheet1Data
    ' will always be a two dimensional array with the first dimension being
    ' the row and the second dimension being the column.

    ' In the first two examples Sheet1Data(5,3) contains the contents
    ' of cell C5.  In the third example, I have only loaded column A but the
    ' array will still has two dimensions but the only permitted value for the
    ' second dimension is 1.

    ' The following statement writes the contents of Sheet1Data to column "E"

    .Range(.Cells(1, 5), .Cells(RowS01Max, 5)).Value = Sheet1Data

  End With

  With Sheets("Sheet2")

    ' The following statement writes the contents of Sheet1Data to column "E"
    ' of worksheet Sheet2.
    .Range(.Cells(1, 5), .Cells(RowS01Max, 5)).Value = Sheet1Data

  End With

End Sub

Не отчаивайтесь!Большинство из нас начали с макро-рекордера и до сих пор используют его для обнаружения синтаксиса незнакомой команды.Посмотри другие вопросы.Некоторые спрашивают об экзотической функциональности, но многие о том, как перенести данные в опытные программиста простыми способами.Настройте несколько рабочих книг с проблемой спрашивающего.Скопируйте и вставьте решение в модуль.Пройдите через него с помощью F8 (см. Отладчик), переключитесь между Excel и Editor, посмотрите, что происходит с рабочим листом, и наведите курсор на переменную, чтобы увидеть ее текущее значение.Проведите полдня, играя.Вы будете удивлены тем, как быстро это начинает иметь смысл.Удачи и хорошего программирования.

3 голосов
/ 06 декабря 2011

Следующие действия должны помочь:

Sub Refresh_Data()
    Dim lastRow As Integer
    Dim lastCol As Integer
    Dim entireRange As Range
    Dim targetRange As Range

    lastRow = Excel.Evaluate("COUNTA(A:A)") ''// count the rows in column A
    lastCol = Excel.Evaluate("COUNTA(1:1)") ''// count the columns in row 1

    Set entireRange = Range(Cells(1, 2), Cells(lastRow, lastCol))
    Set targetRange = Range(Cells(2, 2), Cells(lastRow, lastCol))

    entireRange.FillDown
    Application.Calculate
    targetRange.Copy
    targetRange.PasteSpecial Paste:=xlPasteValues
End Sub

Примечания:

Excel.Evaluate(...) позволяет использовать результат функций листа в макросах VBA.

COUNTA(range) - это функция рабочего листа, которая подсчитывает количество непустых ячеек в заданном диапазоне.В этом случае его можно использовать для определения общего количества строк в вашем наборе данных, а также количества столбцов в строке 1, в которых есть формула.

...