Здравствуйте. Помогите пожалуйста разобраться. Имеется лист с умной таблицей под названием "Таблица1", в ней 10 столбцов с именами "Столбец1" и т.д. Так же имеется код, который обращается к массиву. Вот он:
Код
With Sheets("Sheet2")
iRow = .UsedRange.Row + .UsedRange.Rows.Count - 1: iColl = .UsedRange.Column + .UsedRange.Columns.Count - 1
MyArray = .Range(.Cells(1, 1), .Cells(iRow, iColl)).Value
End With
Set AppWord = CreateObject("Word.Application"): AppWord.Visible = False
'перебираем массив
For I = 2 To iRow
If MyArray(I, 1) = "a" Then
tmpArray = Split(MyArray(I, 3), ";")
For q = 0 To UBound(tmpArray)
tmpSTR = iFolder & tmpArray(q) & ".docx"
If Len(Dir(tmpSTR)) > 0 Then
Set iWord = AppWord.Documents.Open(tmpSTR, ReadOnly:=True)
For J = 4 To iColl
Call ExportWord(MyArray(1, J), MyArray(I, J))
Next J
iWord.SaveAs filename:=BasePath & tmpArray(q) & " - " & MyArray(I, 2) & ".docx", FileFormat:=wdFormatXMLDocument
iWord.Close False: Set iWord = Nothing
End If
'tmpSTR = ""
Next q
'Erase tmpArray
End If
Next I
Мой вопрос состоит в том, как заменить свойства Range на "Таблица1..." и далее грамотно обращаться к нужному столбцу типа "Таблица1[Столбец1]" и т.д. Интуитивно понимаю, что нужно заменить MyArray = .Range(.Cells(1, 1), .Cells(iRow, iColl)).Value на MyArray = .Range("Таблица1").Value, чтобы обозначить массив данных, но как ниже обратиться к нужному столбцу, в моем случае к "Столбец1" и "Столбец3", не догоняю. После слов "перебираем массив", все становится у меня "сложно". Пожалуйста помогите разобрать эту конструкцию.
Dim myTbl As ListObject
Set myTbl = Sheets("Sheet2").ListObjects("Таблица1") 'умная таблица
arrAll_Data = myTbl.DataBodyRange 'получаем массив ВСЕХ данных области данных умной таблицы
arrClm_3 = myTbl.ListColumns(3).DataBodyRange 'массив данных третьего столбца области данных
Как их предоставить?) В макросе есть обработчик ошибок, который выдает мессаджбокс с констатацией факта ошибки, соответственно в отладчик не перекидывает. Там смотрите какое дело, в "моем" коде идет обращение, насколько я понял, к таблице с динамически расширяемым диапазоном, но с начальным адресом привязанным к A1 - Range(.Cells(1, 1). Затем ниже по коду идет обращение к первому и третьему столбцу этого массива для поиска нужных данных - For I = 2 To iRow If MyArray(I, 1) = "a" Then.... Мне же нужно, чтобы я мог обратиться в данной конструкции, к тому или иному столбцу по имени.
Приложить файл-пример. Как есть - Как надо. И измените свое стартовое сообщение - код оформите в соответствии с Правилами форума (как в моем сообщении выше). На панели инструментов значок <...>
Файл-пример во вложении. В модуле iMacro тот кусок кода, который я выложил выше. Собственно мне нужно добавлять строки выше таблицы на листе "data". Если я это сейчас делаю, то макрос не находит нужных данных, так как привязан к первой строке первого столбца. Не могу понять куда "копать"((
Option Explicit
Sub abc_xyz()
Dim i, col, rws, t!
With Sheets("data")
.Select
With .ListObjects("Таблица1")
.HeaderRowRange.Select: t = Timer: While Timer - t < 0.8: DoEvents: Wend
.DataBodyRange.Select: t = Timer: While Timer - t < 0.8: DoEvents: Wend
'Столбце
col = .HeaderRowRange.Count
For i = 1 To col
'.ListColumns(i).Range.Cells(1).Select: t = Timer: While Timer - t < 0.4: DoEvents: Wend
'ili
.HeaderRowRange.Cells(i).Select: t = Timer: While Timer - t < 0.4: DoEvents: Wend
.ListColumns(i).DataBodyRange.Select: t = Timer: While Timer - t < 0.4: DoEvents: Wend
Next
'Строки
rws = .ListRows.Count
For i = 1 To rws
.ListRows(i).Range.Cells(1).Select: t = Timer: While Timer - t < 0.4: DoEvents: Wend
'.ListRows(i).Range.Rows(1).Select: t = Timer: While Timer - t < 0.4: DoEvents: Wend
'ili
.ListRows(i).Range.Select: t = Timer: While Timer - t < 0.4: DoEvents: Wend
Next
End With
.Range("A1").Select
End With
End Sub
Если это так, проверьте (через "F8") шаг за шагом, как вы можете добраться/получить к именам заголовков столбцов и строк, и так далее.
Хорошо, возможно вы правы и больше знаете как и что должно называться. Поэтому сначала) Есть программа (файл примера прикладываю). В ней есть Лист под название "data". В нем есть табличные данные, к которым обращается макрос "iMacro". Я скопировал этот лист и назвал его "data1". На нем я преобразовал обычную таблицу в "умную" и первая строка стала строкой с именами столбцов "умной таблицы". Так как в макросе "iMacro", при обращении к данным на листе "data" прописано с адресацией к строкам и столбцам, при чем вправо и вниз без ограничения с помощью формул, я не имею возможности добавить строки выше существующей первой строки в таблицу на листе "data" без потери работоспособности кода. Вот я и подумал, а что если преобразовать эту таблицу в "умную". Но встала еще одна проблема, я не смог разобраться с обращением непосредственно к именам "умной таблицы" с целью того, чтобы указать макросу откуда брать данные. Вот собственно и вся загвоздка. В принципе я хотел только понять с вашей помощью, как я могу поменять адресацию в макросе, чтобы он начинал верхнюю левую точку отсчета не с A1 (Cells(1,1)...), а со второй, третьей, десятой... Именно для этого я и хотел бы чтобы он (макрос) обращался к именам, а не к адресу ячеек, для динамического изменения размеров массива данных.
Увы, документ не сформировался. Ниже по коду идет обращение к параметру "iRow", значение которого мы удалили. Если не сложно и если у Вас код работает, можете показать работоспособный кусок прямо в файле?
Потрясающе! Вы большой молодец! Благодарю! "А ларчик просто открывался")) Насколько я смог разобраться, в моем примере, I - это строка указанного массива (уже "умной таблицы"), а что такое J?
Sub CreateDoc()
Dim BasePath As String, iFolder As String, iTemplate As String
Dim tmpSTR As String, i As Long, j As Long, t As Variant
Application.ScreenUpdating = 0
On Error GoTo iEnd
iFolder = Range("FILE_WORD").Value: If Right(iFolder, 1) <> "\" Then iFolder = iFolder & "\"
iTemplate = Range("FILE_TEMPLATE").Value: If Right(iTemplate, 1) = ";" Then iTemplate = Left(iTemplate, Len(iTemplate) - 1)
BasePath = ThisWorkbook.Path & "\Result\": Call FolderCreateDel(BasePath)
'создаем скрытый объект Word
Set AppWord = CreateObject("Word.Application"): AppWord.Visible = False
With Range("Таблица1").ListObject
'перебираем строки
For i = 2 To .ListRows.Count + 1
If .ListColumns("Статус").Range(i) = "ok" Then
'перебираем указанные word-шаблоны
For Each t In Split(.ListColumns("Шаблоны для обработки").Range(i), ";")
tmpSTR = iFolder & t & ".docx"
If Len(Dir(tmpSTR)) > 0 Then
Set iWord = AppWord.Documents.Open(tmpSTR, ReadOnly:=True)
'перебираем столбцы
For j = 4 To .ListColumns.Count
'делаем замену переменных
ExportWord .ListColumns(j).Range(1), .ListColumns(j).Range(i)
Next j 'столбец
iWord.SaveAs filename:=BasePath & .ListColumns("Название файла").Range(i) & " - " & t & ".docx", FileFormat:=wdFormatXMLDocument
iWord.Close False: Set iWord = Nothing
End If
Next t 'шаблон
End If
Next i 'строка
End With
AppWord.Quit: Set AppWord = Nothing
'BasePath = "": iFolder = "": iTemplate = ""
Application.ScreenUpdating = 1
MsgBox "Файлы сформированы.", vbInformation
Exit Sub
iEnd:
AppWord.Quit: Set AppWord = Nothing
'BasePath = "": iFolder = "": iTemplate = ""
Application.ScreenUpdating = 1
MsgBox "При обработке данных возникла ошибка.", vbCritical
End Sub
Изменено: Андрей Лящук - 15.09.2019 15:21:24(очепятка)