2016-10-04 1 views
0

Я переформатировал диапазон Sheets("Records") в книге как Table (named "RecordsTable"), чтобы было легче сделать INDEX(MATCH,MATCH) функции для генерации отчетов .... но теперь я прикрутил свою процедуру циклирования для заполнения этого диапазона от ввода на Sheets("FORM").Excel VBA: Как найти первую пустую строку в таблице для цикла Loop?

Раньше считалось:

Set r = Sheets("Records").Range(A & Rows.Count).End(x1Up).Offset(1, 0) 

i = 0 

    For Each c In Range("dataRange")    
    'dataRange is a list of cells to reference from the FORM input sheet 

    r.Offset(0, i).Value = Worksheets("FORM").Range(c) 
    i = i + 1 
Next 

Однако этот код теперь выбрать первую строку в КОНЦЕ "RecordsTable" (строка 501, так как я определил 500 строк в моей таблице) и вставки данных там.

Я попытался изменить его к этому:

Set r = Sheets("Records").ListObjects("RecordsTable").DataBodyRange("A" & Rows.Count).End(x1Up).Offset(1, 0) 

i = 0 

    For Each c In Range("dataRange")    

    r.Offset(0, i).Value = Worksheets("FORM").Range(c) 
    i = i + 1 
Next 

Но этот код все еще выбрать строку 501 и сделать эту строку часть "RecordsTable". Как я могу правильно Set "r" to = первая пустая строка в "RecordsTable"?

Для справки: Column "A" in "RecordsTable" имеет заголовок [INV #]. Кроме того, когда я вхожу в строку "Set r = ...", Rows.Count возвращает значение 1 миллион + (т. Е. Полные строки на листе). Если я правильно понимаю это, я хочу, чтобы оно возвращало значение 500 (т. Е. Полные строки в таблице) - это верно?

EDIT

"dataRange" является единым списком столбца ссылок на ячейки (я бы их маркировку в колонке B, а @chrisneilsen предложить:

J6

Y6

J8

J10

Y8

и т.д.

Они являются клетки на Sheets("FORM"), что мне нужно, чтобы извлекать данные из и заполнить в моей таблице, в порядке, указанном в "dataRange".

+0

Настоящее быстрое предложение: посмотрите, как вы поместили рабочий лист, прежде чем использовать «ListObjects»? Делайте это каждый раз, когда вы используете 'Range()', 'Cells()', 'Rows.Count' и т. Д. Это скажет VBA, какой лист получить эту информацию. В противном случае используется 'ActiveSheet', и это может привести к неожиданным результатам. – BruceWayne

+0

@BruceWayne ^^ спасибо –

ответ

0

Предполагая, что у вас действительно есть таблица, добавление данных в таблицу (ListObject), используя его свойства и методы:

Sub Demo() 
    Dim lo As ListObject 
    Dim c As Range 

    Set lo = Worksheets("Records").ListObjects("RecordsTable") 

    For Each c In Sheets("V").Range("dataRange") 
     If Not lo.InsertRowRange Is Nothing Then 
      lo.InsertRowRange.Cells(1, 1) = Sheets("FORM").Range(c) 
     Else 
      lo.ListRows.Add.Range.Cells(1, 1) = Sheets("FORM").Range(c) 
     End If 
    Next 
End Sub 

Примечание: зацикливание диапазон на листе V и использовать это в качестве указателя данных на листе FORM, скопированный из вашего ответа - я предполагаю, что вы знаете, что вы делаете здесь

на основе ОП комментариев, добавление данных в отдельную строку

Sub Demo() 
    Dim lo As ListObject 
    Dim c As Range, TableRange As Range 
    Dim i As Long 

    Set lo = Worksheetsheets("Records").ListObjects("RecordsTable") 

    If Not lo.InsertRowRange Is Nothing Then 
     Set TableRange = lo.InsertRowRange 
    Else 
     Set TableRange = lo.ListRows.Add.Range 
    End If 
    i = 1 
    For Each c In Sheets("V").Range("dataRange") 
     TableRange.Cells(1, i) = Sheets("FORM").Range(c) 
     i = i + 1 
    Next 
End Sub 

Обратите внимание: это предполагает, что порядок столбцов таблицы совпадает с порядком dataRange.Это может быть лучше включить имена полей таблиц в dataRange, чтобы избежать любого несоответствия вопросы

Как уже упоминалось в обновленном ОП, если заголовки столбцов в следующем столбце, замените For петлю с этим (и добавить Dim r as Range, col as long декларациям)

For Each c In Sheets("V").Range("dataRange") 
     If Not c = vbNullString Then 
      Set r = Worksheets("FORM").Range(c.Value) 
      col = lo.ListColumns(c.Offset(, 1).Value).Index 
      TableRange.Cells(1, col) = r.Value 
     End If 
    Next 
+0

спасибо. Я попытался использовать это, и он правильно добавляет строку в таблицу и запускает ввод данных в первом столбце, но последующие итерации продолжают добавлять данные в первую колонку, следующую доступную строку. У меня есть 40 ячеек, определенных в 'dataRange', и мне нужно, чтобы каждый из них переходил в следующий столбец после того, как он был до него. –

+0

ОК, это новая информация. Итак, вы хотите добавить только одну новую строку и вставить все данные в эту строку? См. Обновление –

+0

Спасибо, Крис. Я пытался работать с тех пор, как вы разместили, и это обновление помогает. Он по-прежнему бросает мне «определенную или определяемую объектом ошибку» в «TableRange.Cells (1, i) =« Таблицы »(« FORM »). Диапазон (c)' хотя. –

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