Дмитрий, спасибо за ответы. Попробую развернуто ответить на ваши вопросы. Сразу оговорюсь, опыта в экселе у меня не много, фактически первый месяц идет как начал на VBA писать.
Вы бы задачу для начала описали более конкретно. А там может и верное решение будет.
У меня большая умная таблица (ListObject) на листе, с большим количеством столбцов. Таблицу наполняют разные пользователя. Один пользователь отвечает за предпечатную подготовку. Что для этого нужно? Пользователю нужно по столбцу "Номер" отобрать строки, в которых есть номера из списка (список номеров пользователю поступает по другому каналу - почта, звонок, устно, мессенджер). Далее нужно скопировать в другую (новую) книгу эти отобранные строки, но не целиком, а только определенные столбцы (номер, фамилия, имя, отчество, срок действия, файл фотографии) и сохранить ее в какую-либо папку. Потом нужно найти фотографии, имена которых есть в отобранных строках (столбец "файл фотографии") и скопировать их в эту же папку. Потом эту папку передать на печать.
Что я хочу сделать.
Я хочу иметь возможность выделить мышкой ячейки, в которых есть требуемые номера (при этом таблица может быть отфильтрована), нажать кнопку и получить готовую папку с новой книгой, в которой записаны выделенные строки (только нужные столбцы, о которых выше писал) и сами файлы фотографий.
Как я вижу решение (копирование файлов фотографий не рассматриваем, это уже реализовал).
Определить номера выделенных строк в контексте ListObject. Создать новую книгу, в ней создать умную таблицу и далее в цикле с помощью Intersect записать содержимое ячеек, которые находятся в выделенных строках и нужных столбцах.
А что должен возвращать, если просили определить строки, выделенные пользователем?
Написал как смог... Получается не достаточно понятно. Виноват.
Писал именно о номерах строках умной таблицы, а не самого листа. Умная таблица начинает не в A1.
И что значит "в контексте таблицы"?
Как бы это объяснить иначе...
К ячейке листа мы обращаемся так -
ThisWorkbook.Worksheets(1).Cells(3,1)
А к ячейке ListObject можно обращаться так
Intersect(ThisWorkbook.Worksheets(1).ListObjects("Table1").ListRows(1).Range, ThisWorkbook.Worksheets(1).ListObjects("Table1").ListColumns("Number").DataBodyRange)
В данном случае это одна и та же ячейка.
Почему Intersect? Потому что я не знаю, в каком порядке будут идти столбцы. А делать перебор столбцов в цикле, чтобы найти где какой, не хочется. Да и как-то не правильным мне это кажется.
А если пользователь выделит строки, которые захватывают и строки умной таблицы и строки вне этой таблицы? Каким должен быть результат?
Нужно проигнорировать строки вне умной таблицы. Интересуют только те строки, которые в пределах умной таблицы.
Я пока смог только такой код сделать, он возвращает номер строки умной таблицы в контексте ListRows, но не правильно работает, если выделение за пределами умной таблицы.
Dim r As Long
Dim i As Long
Dim j As Long
Dim lo As ListObject: Set lo = ThisWorkbook.Worksheets(1).ListObjects("Table1")
Dim ss As Range: Set ss = Selection
Select Case ss.Cells.Rows.Count
Case 1
'выделена одна строка
Debug.Print ss.Cells.Row - lo.HeaderRowRange.Cells(1).Row
Case Is > 1
'выделено несколько строк
For i = 1 To ss.SpecialCells(xlCellTypeVisible).Areas.Count
For j = 1 To ss.SpecialCells(xlCellTypeVisible).Areas.Item(i).Rows.Count
Debug.Print ss.SpecialCells(xlCellTypeVisible).Areas.Item(i).Rows(j).Row - lo.HeaderRowRange.Cells(1).Row
Next j
Next i
End Select
Понимаю, что можно проверить, входит ли строка в умную таблицу или нет. Но пока не разобрался еще...
что мешает определить разницу между выделенной строкой и первой строкой умной таблицы?
На момент задавания вопроса еще не знал, как это сделать. Подсказали в соседней теме.
Я думал, есть какая-то встроенная функция, которая преобразовывает range в номер строки ListObject. Но похоже такой не существует...
И почему Вы всегда оперируете только свойством ListRows? У умных таблиц есть и другие свойства
Потому-что я читаю и пишу умные таблицы через Intersect (т.к. заранее не знаю, где какой столбец), а ему нужно передавать номер строки в контексте ListObject("Table1").ListRows... Т.е. ему нужно указывать номер строки самой умной таблицы, а не номер строки листа. Я не претендую на истину, но я так понял эту функцию. Если не прав, объясните пожалуйста.
Еще одна причина, по которой использую Intersect. Когда работаю с UserForms, то пишу в свойство Tag контролла название столбца, в который должны записываться значения из этого контролла, что очень облегчает написание кода. Ну и еще причина в том, что в этой книге уже очень много кода, который использует Intersect и переписывать его не хочется.
PS: Надеюсь мне удалось понятно ответить на ваши вопросы.