Обращение к ячейке на листе Excel из кода VBA по адресу, индексу и имени. Чтение информации из ячейки. Очистка значения ячейки. Метод ClearContents объекта Range.
Обращение к ячейке по адресу
Допустим, у нас есть два открытых файла: «Книга1» и «Книга2», причем, файл «Книга1» активен и в нем находится исполняемый код VBA.
В общем случае при обращении к ячейке неактивной рабочей книги «Книга2» из кода файла «Книга1» прописывается полный путь:
1 2 3 4 |
Workbooks("Книга2.xlsm").Sheets("Лист2").Range("C5") Workbooks("Книга2.xlsm").Sheets("Лист2").Cells(5, 3) Workbooks("Книга2.xlsm").Sheets("Лист2").Cells(5, "C") Workbooks("Книга2.xlsm").Sheets("Лист2").[C5] |
Удобнее обращаться к ячейке через свойство рабочего листа Cells(номер строки, номер столбца), так как вместо номеров строк и столбцов можно использовать переменные. Обратите внимание, что при обращении к любой рабочей книге, она должна быть открыта, иначе произойдет ошибка. Закрытую книгу перед обращением к ней необходимо открыть.
Теперь предположим, что у нас в активной книге «Книга1» активны «Лист1» и ячейка на нем «A1». Тогда обращение к ячейке «A1» можно записать следующим образом:
1 2 3 4 5 |
ActiveCell Range("A1") Cells(1, 1) Cells(1, "A") [A1] |
Точно также можно обращаться и к другим ячейкам активного рабочего листа, кроме обращения ActiveCell, так как активной может быть только одна ячейка, в нашем примере – это ячейка «A1».
Если мы обращаемся к ячейке на неактивном листе активной рабочей книги, тогда необходимо указать этот лист:
1 2 3 4 |
'по основному имени листа Лист2.Cells(2, 7) 'по имени ярлыка Sheets("Имя ярлыка").Cells(3, 8) |
Имя ярлыка может совпадать с основным именем листа. Увидеть эти имена можно в окне редактора VBA в проводнике проекта. Без скобок отображается основное имя листа, в скобках – имя ярлыка.
Обращение к ячейке по индексу
К ячейке на рабочем листе можно обращаться по ее индексу (порядковому номеру), который считается по расположению ячейки на листе слева-направо и сверху-вниз.
Например, индекс ячеек в первой строке равен номеру столбца. Индекс ячеек во второй строке равен количеству ячеек в первой строке (которое равно общему количеству столбцов на листе, зависящему от версии Excel) плюс номер столбца. Индекс ячеек в третьей строке равен количеству ячеек в двух первых строках плюс номер столбца. И так далее.
Для примера, Cells(4) та же ячейка, что и Cells(1, 4). Используется такое обозначение редко, тем более, что у разных версий Excel может быть разным количество столбцов и строк на рабочем листе.
По индексу можно обращаться к ячейке не только на всем рабочем листе, но и в отдельном диапазоне. Нумерация ячеек осуществляется в пределах заданного диапазона по тому же правилу: слева-направо и сверху-вниз. Вот индексы ячеек диапазона Range(«A1:C3»):
Обращение к ячейке Range("A1:C3").Cells(5)
соответствует выражению Range("B2")
.
Обращение к ячейке по имени
Если ячейке на рабочем листе Excel присвоено имя (Формулы –> Присвоить имя), то обращаться к ней можно по присвоенному имени.
Допустим одной из ячеек присвоено имя – «Итого», тогда обратиться к ней можно – Range("Итого")
.
Запись информации в ячейку
Содержание ячейки определяется ее свойством «Value», которое в VBA Excel является свойством по умолчанию и его можно явно не указывать. Записывается информация в ячейку при помощи оператора присваивания «=»:
1 2 3 4 |
Cells(2, 4).Value = 15 Cells(2, 4) = 15 Range("A1") = "Этот текст записываем в ячейку" ActiveCell = 28 + 10*36 |
Вместе с числами и текстом можно использовать переменные. Примеры здесь и ниже приведены для активного листа. Для неактивных листов дополнительно необходимо указывать имя листа, как в разделе «Обращение к ячейке».
Чтение информации из ячейки
Считать информацию из ячейки в переменную можно также при помощи оператора присваивания «=»:
1 2 3 4 5 6 7 8 9 |
Sub Test() Dim a1 As Integer, a2 As Integer, a3 As Integer Range("A3") = 6 Cells(2, 5) = 15 a1 = Range("A3") a2 = Cells(2, 5) a3 = a1 * a2 MsgBox a3 End Sub |
Точно также можно обмениваться информацией между ячейками:
1 |
Cells(2, 2) = Range("A4") |
Очистка значения ячейки
Очищается ячейка от значения с помощью метода ClearContents. Кроме того, можно присвоить ячейке значение нуля, пустой строки или Empty:
1 2 3 4 |
Cells(10, 2).ClearContents Range("D23") = 0 ActiveCell = "" Cells(5, "D") = Empty |
Это продолжение вчерашнего получается. Есть у меня Книга Excel, под названием Прайс (в процессе создания). И есть столбец с наименованием товара. В этом столбце попадаются такие:
Газоанализатор HORIBA APSA-370(SO2)
Газоанализатор HORIBA APNA-370(NO,NO2,NOx)
Газоанализатор HORIBA APSA-370(H2S)
ну и тому подобное. Столбец там не один, но именно к этому вопрос
Проблема в следующем:
В другую книгу Excel я выдергиваю данные из книги Прайс при помощи ВПР следующим образом:
В ячейку (предположим С5) я ввожу искомое значение. В другой ячейке создаю ВПР которое по совпадению в книге Прайс с написанным значением в С5 выдергивает нужный мне параметр.
Но приходится писать полное название в С5 — Газоанализатор HORIBA APSA-370(H2S). Позиции отличаются в написании только в конце. Пробовал выпадающий список. Но он не работает с закрытыми книгами.
Можно ли каким либо образом настроить ВПР так, чтобы поиск велся не с первых символов введенных в ячейки Книги Прайс где ВПР ищет совпадения, а по всей ячейке в сочетании символов.
Например я в ячейке С5 начинаю вводить HOR а мне предлагался бы выбрать из нескольких ячеек, где встречается словосочетание HOR. Имеется в виду HORIBA. Или же только один вариант — создавать все в одной книге но на разных листах и с выпадающим списком?
Константин, я предпочитаю все создавать в одной книге, но для вашего случая тоже есть решение.
На одном из листов текущей книги любой столбец свяжите формулой массива со столбцом с наименованиями книги Прайс. Обе книги должны быть с одинаковым количеством строк на листах.
Все изменения в столбце с наименованиями книги Прайс будут переноситься в текущую книгу. Столбец текущей книги с перенесенными наименованиями, а лучше часть его, используйте для задания диапазона раскрывающегося списка. Если использовать для раскрывающегося списка целый столбец, в конце списка будет очень много позиций с нулями.
Спасибо за совет
Добрый вечер!
Может вопрос покажется довольно элементарно простым но все же…
Как прописать в таблице MSExcell VBA код так, чтобы в при обозначении ячейки символом, или буквой, таблица считала ее как цифра? Например: ячейка A1: буква «А» равен 1., буква «Б» равна 2 и т.д. То есть всем буквам алфавита присвоены конкретные числовые значения. Далее в отдельной ячейке все эти значения суммируются до однозначного числа. Можно ли сделать так чтобы в одну ячейку записано слово из нескольких букв и в другой ячейке автоматически высчитывается суммарное численное значение каждой буквы?
Привет, Бурхан!
Заполните буквами алфавита первый столбец, начиная с первой ячейки. Тогда номер строки будет соответствовать порядковому номеру буквы в алфавите. Найти букву и ее порядковый номер поможет метод Find:
Добрый день. Подскажите, пожалуйста, возможно ли с помощью VBA в Excel реализовать следующее:
Есть лист с данными. Первая колонка содержит названия городов. В ней значения на разных строках могут повторяться (в таблице может быть несколько разных записей с одним и тем же городом в первой колонке). Остальные колонки заполнены различными неповторяющимися данными (например, адресами). Причем в разных строках может быть разное количество заполненных столбцов (адресов).
Задача:
Нужно «слепить» строки с одинаковыми городами в одну строку (Для каждого города должна получиться одна строка с идущими подряд данными, которые прежде были в разных строках). Естественно, само название города должно остаться только в первой ячейке каждой строки.
Заранее большое спасибо!
Добрый день, Андрей!
Реализовать такую задачу в VBA можно, но простого решения нет.
В первую очередь надо отсортировать данные по наименованиям городов и вручную исправить в наименованиях городов ошибки, если они есть.
Далее код VBA должен просматривать строки по очереди, каждый новый город записывать в первую ячейку новой строки на новом листе, а в следующие ячейки этой строки записывать данные из всех строк с этим городом исходной таблицы, начиная со второй ячейки. Для реализации такого кода используются условия и циклы.
Такой код будет работать медленно, что будет заметно при обработке больших таблиц. Для ускорения можно использовать массив, в который скопировать информацию из исходной таблицы с отсортированными строками и вставлять данные на новый лист уже из него.
Евгений, большое спасибо за ответ. Пусть код будет работать медленно — это все же намного лучше, чем переносить все данные руками. Логику нужного кода я примерно представляю, но не знаю, как все это описать в применении к Excel, даже без использования дополнительного массива. Алгоритм, насколько я понимаю, должен выглядеть примерно так (Таблица отсортирована по названиям городов, опечатки отсутствуют):
переменная (x) с названием города из первой ячейки первой строки;
переменная (n) с номером первой строки — изначально равна 1;
переменная (m) с номером второй строки — изначально равна 2;
переменная (q) с номером строки на новом листе, куда будем вставлять — изначально равна 1;
скопировать все заполненные ячейки первой строки в первую строку на новом листе;
цикл по условию m <= числу заполненных строк на текущем листе:
если:
— город в строке m совпадает со значением переменной x;
то:
— скопировать все заполненные ячейки, начиная со второй, из строки m;
— вставить их, начиная с первой свободной ячейки, в строку q на новом листе;
— увеличить m на 1;
иначе (если город в строке m не равен значению переменной x):
— записать значение из m в n;
— записать в x значение города из строки n;
— увеличить m на 1;
— увеличить q на 1;
— записать в строку q на новом листе все заполненные ячейки из строки n текущего листа;
конец цикла;
Помогите, пожалуйста, перевести это на VBA 🙂 Очень благодарен!
Андрей, решение вашей задачи я опубликую в отдельной статье, когда у меня будет свободное время. По сроку не сориентирую. Ссылку дам, когда будет готово.
Евгений, большое спасибо. Если у меня получится разобраться раньше — напишу свое решение сюда же.
Добрый день, Андрей и Евгений.
Андрей,
Решить вашу задачу можно не прибегая к программированию на VBA, хотя на данном ресурсе Евгения есть вся необходимая для решения задачи информация.
Для решения нужно прибегнуть к иснтрументу Power Query, который с 2016 входит в состав экселя, в для 2010 и 2013 можно бесплатно скачать и доустановить.
В Power Query при помощи запроса №1 необходимо выполнить отмену свертывания столбцов (для вашей задачи это различные адреса) и выполнить сортировку по городам.
Далее при помощи запроса №2 сформировать уникальные города (список уникальных можно сформировать и штатными средствами экселя).
И затем при помощи формул и использования главным образом функций ДВССЫЛ, ТРАНСП, ПОИСКПОЗ, СТРОКА и формулы массивов можно реализовать поставленную задачу.
Андрей, решение вашей задачи опубликовано в отдельной статье.
Евгений,
в статье в примере вы указали
Workbooks(«Книга2.xlsm»).Sheets(«Лист2»).Cells(5, 3)
неплохо было бы отметить еще один способ
Workbooks(«Книга2.xlsm»).Sheets(«Лист2»).Cells(5, «C»)
Спасибо, Фарин, за дополнение. Добавил и этот способ указания индекса столбца.
Нужно создать код процедуры, позволяющей ввести данные в ячейки
таблицы В2:Е4, пользуясь обращением к ячейкам таблицы Cells(строка,
столбец) и диалоговым окном InputBox
Привет, Анна!
Евгений, помогите пожалуйста. Есть код. Ячейки из одной таблицу ищут совпадение с ячейками из другой. При совпадении в первой таблице напротив ячейки ставится «1». Во второй таблице значения с которыми сравнивают упорядочены и смысла пробегать с первой строки нет, пытаюсь сделать чтобы Find искал уже после предыдущей найденной строки с помощью After, но не получается правильно записать переменную в качестве номера строки.
a = Timer
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayAlerts = False
Set Lst1 = Worksheets(«2»)
Set Lst = Worksheets(«1»)
i = 1
k = 1
Do While Lst.Cells(i, 1) «»
ll1 = Lst.Cells(i, 9)
Set nseek = Lst1.Range(«F:F»).Find(What:=ll1, After:=Range(«F» & k), LookIn:=xlValues, LookAt:=xlWhole)
If Not nseek Is Nothing Then
Lst.Cells(i, 10).Value = «1»
k = nseek.Row
End If
i = i + 1
Loop
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
MsgBox Timer — a
Как правильно записать After:=Range(«F» & k)
Виталий, формула Range(«F» & k) рабочая. Попробуйте использовать FindNext со второго поиска. Первый поиск методом Find до цикла, а далее в цикле FindNext.
День добрый, Евгений. Прошу подскажите с кодом для перехода на другой лист . Как это можно это сделать через макрос привязанный к кнопке . т.е. на листе список с названием всех листов и одна кнопка при нажатии переход на лист а имя листа берется из под активного курсора. Если указать имя конкретного листа понятно , то будет так
, а как чтобы имя листа бралось из под курсора ?
Привет, Игорь!
Код должен быть размещен в модуле листа со списком наименований листов.
Вместо
Range("A1:A5")
– ваш диапазон ячеек с наименованиями листов.Добрый день или вечер у меня не большой вопрос может он покажется глупым я уже давно не использовал ВБА поэтому надеюсь поможете
Есть макрос который пишет в ячейке А2 вермя в настоящий момент так вот я бы хотел сделать следующее при нажатии на кнопку второй раз заполнялась следующая ячейка тоесть А2 это я привёл простейший пример просто не могу вспомнить как обозначить что ячейка занята
Если вы поможете буду очень признателен.
Здравствуйте, Юрий!
Если я правильно понял ваш вопрос, тогда ответ может быть таким:
Обсуждение закрыто.