Нумерация листов vba excel

Студворк — интернет-сервис помощи студентам

Условие следующее
Есть произвольные книги Excell
В книгах разное количество листов. НЕ СТРАНИЦ А ИМЕННО ЛИСТОВ Sheet
Порядок действий
Я открываю книгу, на первом листе в ячейке D1 указываю номер листа (1),
выделяю листы и запускаю макрос.
Результат.
Лист 1 ячейка D1 значение 1
Лист 2 ячейка D1 значение 2
Лист n+1 ячейка D1 значение n+1
В идеале выделенные листы, обрабатываются. Приемлемый если все подряд в книге перезаписывпются в ячейке

Добавлено через 27 минут
Во всех вышеперечисленных темах нет нужной информации именно потому и создал тему. Нумерация страниц по листам это типовой функционал

Добавлено через 1 минуту
Все не то.

Rust
Новичок
Новичок
 
Сообщения: 42
Зарегистрирован: 01.02.2005 (Вт) 14:41

Расположение и нумерация листов в книге Excel.

Здравствуйте!

Есть книга, в которой первые четыре листа служебные (Лист2, Лист3, Лист4 скрыты).

NameSheet=»НовЛист»

Из кода VBA создаётся новый лист на основе шаблона(Лист2).

ThisWorkbook.Sheets(«Лист2»).Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Worksheets.Count)

ActiveSheet.Name = NameSheet

Почему новый лист оказывается между Листами 2 и 3?

Этот код показывает, что индексы листов изменились.

For i = 1 To ThisWorkbook.Worksheets.Count

ПроверяюИндексЛиста= Sheets(i).Name

Next i

Как сделать так, чтобы первые четыре листа оставались в пределах индексов с 1 по 4, а все вновь создаваемые с 5 и далее.

Т.к. пользователь должен работать(создавать, удалять, редактировать) только новые листы и обработка этих данных у меня реализована примерно так:

For i = 5 To ThisWorkbook.Worksheets.Count

‘ Работаем с данными

Next i


Rust
Новичок
Новичок
 
Сообщения: 42
Зарегистрирован: 01.02.2005 (Вт) 14:41

Сообщение Rust » 30.01.2008 (Ср) 8:50

Пока думаю в цикле пропускать служебные листы, сравнивая по имени. Но может есть другой способ?


anvg
Обычный пользователь
Обычный пользователь
 
Сообщения: 66
Зарегистрирован: 20.05.2007 (Вс) 18:04

Сообщение anvg » 30.01.2008 (Ср) 10:14

Rust

А зачем?

Пока думаю в цикле пропускать служебные листы

Установите следующий порядок в книге. Служебные скрытые листы идут первыми. Единственный видимый лист последним. Тогда создаваемый по шаблону лист будет иметь наибольший индекс. Цикл же будет начинаться с индекса видимого листа по последний.

С другой стороны, можно создавать листы по шаблону из книги с одним листом-шаблоном, что позволит исключить скрытые листы.

Код: Выделить всё
ThisWorkbook.Sheets.Add Type:="pathmyblanksheet.xls"

Только как вы будете контролировать произвольно созданные пользователем листы?


Rust
Новичок
Новичок
 
Сообщения: 42
Зарегистрирован: 01.02.2005 (Вт) 14:41

Сообщение Rust » 30.01.2008 (Ср) 10:37

Пользователем будут создаваться, редактироваться и удаляться листы только из формы. Структура книги будет защищена. Все листы, кроме Главного будут скрыты, поэтому я хочу всё управление листами осуществлять из кода.


Rust
Новичок
Новичок
 
Сообщения: 42
Зарегистрирован: 01.02.2005 (Вт) 14:41

Сообщение Rust » 30.01.2008 (Ср) 16:30

anvg, Спасибо!

Воспользовался советом. Всё работает отлично.

Хотя, странно, почему новому листу присваивается индекс, следующий за последним отображённым листом, а не индекс, следующий за последним по порядку листом Книги.



Вернуться в VBA

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

 

Андрей_26

Пользователь

Сообщений: 647
Регистрация: 30.01.2018

Добрый день!
Есть книга excel c несколькими листами. На листах различное количество страниц, которое будет постоянно меняться. В книге есть макрос, который сохраняет выбранные листы в один файл формата   .pdf. При сохранении в конце каждой страницы (кроме титульной) должны быть колонтитулы:
— внизу по центру: с указанием номера текущей страницы листа
— внизу справа: с указанием сквозной нумерации
Таким образом хотелось бы видеть:
Страница протокола 1              Страница отчета 2
Страница протокола 2              Страница отчета 3
Страница протокола 1              Страница отчета 4
Страница протокола 2              Страница отчета 5
Страница протокола 3              Страница отчета 6
Страница протокола 4              Страница отчета 7  и т.д.
У меня же получается сделать либо сквозную нумерацию, либо постраничную. Как их объединить в одном колонтитуле, кто что подскажет ?

Попробуйте запустить макрос и сохранить файл (сохранится в той же папке) . Откройте файл pdf и посмотрите на колонтитулы со второго листа и далее. И что хотелось бы в сообщении #1

Прикрепленные файлы

  • Пример.xlsm (41.29 КБ)

Изменено: Андрей_2616.01.2020 19:20:46

 

Андрей VG

Пользователь

Сообщений: 11878
Регистрация: 22.12.2012

Excel 2016, 365

Доброе время суток.
Скорее всего создать для страниц с протоколами раздельные нижние колонтитулы для чётных и нечётных страниц в для чётных вписасть «Страница протокола 1», для нечётных «Страница протокола 2». Или я чего-то не понял.

 

Андрей_26

Пользователь

Сообщений: 647
Регистрация: 30.01.2018

Номера страниц формируются автоматически. В файле примере: Лист «Титул» — занимает 1 страницу, Лист «Протокол-1» — занимает 2 страницы, Лист «Протокол-4» — занимает 11 страниц). Итого имеет 14 страниц.
Для того чтобы подсчитывалось кол-во страниц на каждом листе в колонтитуле указываем: «Страница протокола &[Страница]»,
Для сквозной нумерации всех страниц в колонтитуле указываем «Страница отчета  &С&[Страница]».
Но дело в том, что если на каждом листе в настройках выбрать:
1) Параметры страницы — страница — номер первой страницы — Авто     тогда результат будет таким (сквозная нумерация всего)
Страница протокола 2              Страница отчета 2
Страница протокола 3              Страница отчета 3
Страница протокола 4              Страница отчета 4
……………………………………………………………………….
Страница протокола 14            Страница отчета 14

2) Параметры страницы — страница — номер первой страницы — 1          тогда результат будет таким  (постраничная нумерация каждого листа excel)
Страница протокола 1              Страница отчета 1
Страница протокола 2              Страница отчета 2
Страница протокола 1              Страница отчета 1
Страница протокола 2              Страница отчета 2
Страница протокола 3              Страница отчета 3
……………………………………………………………………….
Страница протокола 11            Страница отчета 11

А мне нужно сделать так:
Страница протокола 1              Страница отчета 2
Страница протокола 2              Страница отчета 3
Страница протокола 1              Страница отчета 4
Страница протокола 2              Страница отчета 5
Страница протокола 3              Страница отчета 6
……………………………………………………………………….
Страница протокола 11            Страница отчета 14

Возможно ли это в принципе стандартными средствами Excel ?

 

Андрей VG

Пользователь

Сообщений: 11878
Регистрация: 22.12.2012

Excel 2016, 365

Андрей, в вашем конкретном случае, когда есть только два значения Страница протокола 1 и Страница протокола 2 — можно решить настройкой отдельных колонтитулов для чётных и нечётных страниц.

Прикрепленные файлы

  • Path.zip (185.34 КБ)

 

Андрей_26

Пользователь

Сообщений: 647
Регистрация: 30.01.2018

Андрей VG

я понял принцип который вы предложили. Но к сожалению если посмотреть файл pdf с шестой страницы то получается:
Страница протокола 1              Страница отчета 6
Страница протокола 2              Страница отчета 7
Страница протокола 1              Страница отчета 8
Страница протокола 2              Страница отчета 9
А должно быть:
Страница протокола 3             Страница отчета 6
Страница протокола 4             Страница отчета 7
Страница протокола 5             Страница отчета 8
Страница протокола 6             Страница отчета 9

Еще раз попробую объяснить. Смотрите, есть сквозная нумерация внизу справа — она работает правильно. Всего листов в создаваемом отчете — 14. В книге есть листы такие как «Протокол-1» на данном листе 2 печатные страницы, т.е. нумерация по середине должна идти Страница протокола 1,  Страница протокола 2. Следующий лист книги «Протокол-4» в нем 11 листов, нумерация по середине должна идти Страница протокола 1, Страница протокола 2……Страница протокола 11.

Изменено: Андрей_2616.01.2020 19:03:12

 

Андрей VG

Пользователь

Сообщений: 11878
Регистрация: 22.12.2012

Excel 2016, 365

#6

16.01.2020 19:49:36

Цитата
Андрей_26 написал:
А должно быть:Страница протокола 3             Страница отчета 6
Страница протокола 4             Страница отчета 7

А вот этого в стартовом сообщении было ничего. :)
Теоретически, переразбив по другому на листы, можно что-то вроде такого применить.

Прикрепленные файлы

  • Path.zip (219.24 КБ)

 

Андрей_26

Пользователь

Сообщений: 647
Регистрация: 30.01.2018

#7

16.01.2020 20:55:12

Цитата
Андрей VG написал:
А вот этого в стартовом сообщении не было ничего.

Да, я исправил, что бы было более понятно сразу тем кто читает в первый раз.
А предложенный Вами вариант я рассматривал, только на примере «Страница отчета  &С&[Страница]+1 » (добавления листов к сквозной нумерации), но это крайняя мера, т.к. это не удобно вот почему: планируется что в книге будет порядка 10 листов  (Протокол -1, Протокол-2 и т.д.) Каждый протокол может занимать от 1 до 300 страниц и по мимо этого планируется сделать выбор: какие протокола добавлять в отчет, а какие нет. Если прибегать к данному методу то нужно будет писать макрос по добавлению на каждый лист колонтитула с указанием какое кол-во листов  вычитать/добавлять — а этого ой как ни хочется ))  Например представьте такой набор в книге:
Титульный лист — 1 страница
Протокол 1         — 3 страницы
Протокол 2         — 10 страниц
Протокол 3         — 17 страниц
Протокол 4         — 59 страниц
Протокол 5         — 38 страниц
Пользователь выбрал для сохранения: Титульный лист, Протокол 2, Протокол 4 и Протокол 5.
А в следующий раз выберет: Титульный лист, Протокол 1, Протокол 3, Протокол 5.                 Я просто запутаюсь в вычислении нужного кол-ва листов.
Поэтому мне ни понятно почему в excel по отдельности использовать сквозную нумерацию, либо постраничную можно, а вместе ни чего не получается ?

Изменено: Андрей_2616.01.2020 21:02:55

 

Андрей VG

Пользователь

Сообщений: 11878
Регистрация: 22.12.2012

Excel 2016, 365

#8

16.01.2020 22:17:47

Цитата
Андрей_26 написал:
либо постраничную можно

Скорее всего так, настраивая колонтитул для каждой страницы и сохраняя либо каждую в отдельный pdf, а потом слияние в один, либо использовать что-нибудь типа Pdf Creator, что позволяют «печатать» в один и тот же pdf-файл, а потом сохранять.

автоматическая нумерация страниц без применения колонтитулов

ovechkin1973

Дата: Вторник, 17.01.2017, 14:58 |
Сообщение № 1

Группа: Проверенные

Ранг: Обитатель

Сообщений: 429


Репутация:

1

±

Замечаний:
0% ±


Excel 2010

Есть бланк определенной формы.. необходимо в нем сделать в определенных ячейках нумерацию страниц начиная со второй и подставлять значение количества страниц на первом листе. Каким способом это сделать можно..

К сообщению приложен файл:

2059552.xlsx
(26.6 Kb)


Плохо когда не знаешь, да еще забудешь. Правильно сформулированный вопрос содержит половину ответа.

 

Ответить

AlexM

Дата: Вторник, 17.01.2017, 15:28 |
Сообщение № 2

Группа: Друзья

Ранг: Участник клуба

Сообщений: 4257


Репутация:

1046

±

Замечаний:
0% ±


Excel 2003

необходимо в нем сделать в определенных ячейках нумерацию страниц начиная со второй

У вас в примере всего одна ячейка для всех страниц D21



Номер мобильного модема (без голосовой связи)
9269171249 МегаФон, Московский регион.

 

Ответить

ovechkin1973

Дата: Вторник, 17.01.2017, 15:40 |
Сообщение № 3

Группа: Проверенные

Ранг: Обитатель

Сообщений: 429


Репутация:

1

±

Замечаний:
0% ±


Excel 2010

У вас в примере всего одна ячейка для всех страниц D21

Не совсем так.. это сквозная строка и печатается на каждом листе.. Если нажать режим просмотра и полистать вниз, то видно.


Плохо когда не знаешь, да еще забудешь. Правильно сформулированный вопрос содержит половину ответа.

 

Ответить

AlexM

Дата: Вторник, 17.01.2017, 15:57 |
Сообщение № 4

Группа: Друзья

Ранг: Участник клуба

Сообщений: 4257


Репутация:

1046

±

Замечаний:
0% ±


Excel 2003

Я это видел, поэтому написал, ячейка одна и значение в ней будет одно сквозное по всем листам.



Номер мобильного модема (без голосовой связи)
9269171249 МегаФон, Московский регион.

 

Ответить

ovechkin1973

Дата: Вторник, 17.01.2017, 15:58 |
Сообщение № 5

Группа: Проверенные

Ранг: Обитатель

Сообщений: 429


Репутация:

1

±

Замечаний:
0% ±


Excel 2010

т.е. без колонтитулов ни как? А как тогда общее количестве листов можно посчитать, чтобы в автоформу вставить?


Плохо когда не знаешь, да еще забудешь. Правильно сформулированный вопрос содержит половину ответа.

 

Ответить

Alex_ST

Дата: Вторник, 17.01.2017, 16:01 |
Сообщение № 6

Группа: Друзья

Ранг: Участник клуба

Сообщений: 3176


Репутация:

604

±

Замечаний:
0% ±


2003

А Вы надеялись, что в ячейках сквозных строк может быть разное значение? :)
На то они и сквозные, что хоть и печатаются на каждом листе, но это только видимость, т.к. реально существуют в единственном экземпляре.
Так что с колонтитулами — это скорее всего самое то, что надо.



С уважением,
Алексей
MS Excel 2003 — the best!!!

 

Ответить

AlexM

Дата: Вторник, 17.01.2017, 16:02 |
Сообщение № 7

Группа: Друзья

Ранг: Участник клуба

Сообщений: 4257


Репутация:

1046

±

Замечаний:
0% ±


Excel 2003



Номер мобильного модема (без голосовой связи)
9269171249 МегаФон, Московский регион.

 

Ответить

Alex_ST

Дата: Вторник, 17.01.2017, 16:25 |
Сообщение № 8

Группа: Друзья

Ранг: Участник клуба

Сообщений: 3176


Репутация:

604

±

Замечаний:
0% ±


2003

Да, тёзка, вот ЭТО, похоже, должно работать.
Только надо подумать, как чуть подпилить, чтобы не жёстко задавать столбец для ячеек с номерами страниц…
Может быть, перед началом нумерации предложить юзеру выделить столбец?
А про HPageBreaks я к стыду своему даже не слышал. :'(



С уважением,
Алексей
MS Excel 2003 — the best!!!

 

Ответить

ovechkin1973

Дата: Вторник, 17.01.2017, 18:21 |
Сообщение № 9

Группа: Проверенные

Ранг: Обитатель

Сообщений: 429


Репутация:

1

±

Замечаний:
0% ±


Excel 2010

Спасибо за участие.. ссылки все пересмотрел. Как использовать в своих целях макрос не понял. Осилил только колонтитулы в правом нижнем углу каждой страницы .. типа 1 из 5.. как посчитать общее количество листов не представляю


Плохо когда не знаешь, да еще забудешь. Правильно сформулированный вопрос содержит половину ответа.

 

Ответить

AlexM

Дата: Вторник, 17.01.2017, 19:06 |
Сообщение № 10

Группа: Друзья

Ранг: Участник клуба

Сообщений: 4257


Репутация:

1046

±

Замечаний:
0% ±


Excel 2003

[vba]

Код

Function Sheet_Page_Count(iSheet As String) As Long
Sheet_Page_Count = Sheets(iSheet).HPageBreaks.Count + 1
End Function

[/vba]



Номер мобильного модема (без голосовой связи)
9269171249 МегаФон, Московский регион.

 

Ответить

ovechkin1973

Дата: Вторник, 17.01.2017, 19:40 |
Сообщение № 11

Группа: Проверенные

Ранг: Обитатель

Сообщений: 429


Репутация:

1

±

Замечаний:
0% ±


Excel 2010

AlexM, я перенес макрос в свой файл и вставил «&Sheet_Page_Count(«Шапка») на лист «заполнение шапки» в ячейку G7. Из нее уже в автоформу на листе «Шапка» вставил.
Если начать добавлять листы или убирать не меняются значения.. что не так делаю?
Точнее что надо делать, чтобы пересчет был, если добавили листы или убрали?
Я в макрос абсолютный нуль.. могу только их вставлять в свои файлы.. да и то, если все просто.
Правда если встать в ячейку, где написано Sheet_Page_Count(«Шапка») и нажать энтер, то перерасчет происходит

К сообщению приложен файл:

____.xlsm
(35.2 Kb)


Плохо когда не знаешь, да еще забудешь. Правильно сформулированный вопрос содержит половину ответа.

 

Ответить

AlexM

Дата: Вторник, 17.01.2017, 19:53 |
Сообщение № 12

Группа: Друзья

Ранг: Участник клуба

Сообщений: 4257


Репутация:

1046

±

Замечаний:
0% ±


Excel 2003

добавьте к функции функцию СЕГОДНЯ() так

Код

=Sheet_Page_Count(«Шапка»)+СЕГОДНЯ()*0



Номер мобильного модема (без голосовой связи)
9269171249 МегаФон, Московский регион.

 

Ответить

ovechkin1973

Дата: Вторник, 17.01.2017, 21:03 |
Сообщение № 13

Группа: Проверенные

Ранг: Обитатель

Сообщений: 429


Репутация:

1

±

Замечаний:
0% ±


Excel 2010

Ура! заработало!!! Глупый вопрос — я в ячейку что вставил? Сегодня — это формула.. а перед этим? И как это с макросом связано?
В любом случае очень благодарен


Плохо когда не знаешь, да еще забудешь. Правильно сформулированный вопрос содержит половину ответа.

 

Ответить

AlexM

Дата: Вторник, 17.01.2017, 21:45 |
Сообщение № 14

Группа: Друзья

Ранг: Участник клуба

Сообщений: 4257


Репутация:

1046

±

Замечаний:
0% ±


Excel 2003

Глупый вопрос — я в ячейку что вставил? Сегодня — это формула.. а перед этим?

перед СЕГОДНЯ() функция пользователя Sheet_Page_Count(«Шапка») в аргументе имя листа. СЕГОДНЯ()*0 есть ноль, что не как не влияет на результат функции пользователя. Однако функция СЕГОДНЯ() пересчитывается при любых изменениях на листе, а так как эта функция в составе формулы, то пересчитывается формула.



Номер мобильного модема (без голосовой связи)
9269171249 МегаФон, Московский регион.

 

Ответить

ovechkin1973

Дата: Среда, 18.01.2017, 17:22 |
Сообщение № 15

Группа: Проверенные

Ранг: Обитатель

Сообщений: 429


Репутация:

1

±

Замечаний:
0% ±


Excel 2010

Понял.. положу в «копилку» такое решение себе..


Плохо когда не знаешь, да еще забудешь. Правильно сформулированный вопрос содержит половину ответа.

 

Ответить

Последнее время на работе занималась приведением excel-файлов к виду, при котором пользователь может допустить наименьшее количество ошибок при заполнении. До этого первый и последний раз я сталкивалась с visual basic в школе, причем не применительно к Ms Excel, поэтому потребовалось некоторое время на то, чтобы понять, как делать простые и, и тем более не очень, вещи. Эта статейка может помочь людям, оказавшимся в похожей ситуации, быстрее войти в курс дела. Демо-экселька прилагается.


Основы

Самый первый вопрос, который у меня возник, после того как вкладка «Разработчик» была добавлена (подробнее тут, например) и открыт встроенный vba-редактор, это куда собственно писать код. По умолчанию в книге есть модули страниц, модуль книги и один общий модуль. Существуют также модули формы и классов, но сейчас речь не о них. Все вполне логично: обработку событий на объекты страницы пишем в соответствующий лист страницы, обработку событий для книги — в модуль книги, а общие функции для всех листов — в общий модуль. При этом имеет смысл создать еще модули для отделения функционала по смыслу.

Также сразу возникает вопрос, а как элементарно обратиться к ячейке, найти ее значение и перезаписать его. Очень просто:

‘ в ячейку А1 пишем «add note» + значение ячейки B1
Cells(1,1).Value = «add note » & Cells(1,2).Value

For Each oCell In Range(«A1:A10»).Cells
     ‘обработка 
     oCell.Value = oCell.Row ‘ присвоили номер строки   
Next 

Моим следующим вопросом было каким образом вернуть значение из функции. В vba есть два типа функций: sub и function. Разница в том, что function как раз и умеет возвращать значение, для этого в коде функции надо написать ИмяФункции = возвращаемое_значение:

Public Function insertRow()
    Dim position As Integer
    ‘…
    insertRow = position ‘возвращаемое значение

End Function

После написания нескольких функций во встроенном редакторе, меня нешуточно заинтересовало, как перенести строку кода на следующую физическую строку. Если посреди строки кода нажать enter, кроме ошибки мы ничего не добьемся. Оказывается, надо использовать «_»:

If ActiveSheet.Index = 1 _
   Or ActiveSheet.Index = 4 Then
        ‘ действия
End If

Нарочно и не придумаешь.

Помимо массивов, в VBA следует обратить внимание на коллекции. Работать с ними просто:

Dim сoll As New Collection
сoll.Add («элемент1»)‘добавляем элемент
сoll.Add («элемент2»)‘размер увеличивается динамически
‘ по умолчанию индекс начинается с 1, можно изменить
MsgBox (сoll.Item(1)) элемент1
сoll.Remove (1) ‘ удаляем первый элемент
MsgBox (сoll.Count)‘выводим размер коллекции

Чтобы когда мы творим беспредел с нашим excel-файликом посредством vba, он предательски не корчился и напоказ не дергал строками и столбцами перед пользователем (например, при удалении и скрытии интервалов), можно отключать прорисовку:

Application.ScreenUpdating = False ‘ значение True включает

Автоматическая нумерация строк таблицы

Одной из первых моих мелких подзадач стала нумерация строк таблицы. Можно, конечно, при добавлении строки вставлять номер функцией, но хотелось по возможности чтобы это происходило само собой. Как выяснилось, нумеровать ячейки можно формулой =СТРОКА(ячейка), которая возвращает номер строки ячейки-параметра. Например, формула =СТРОКА(А1), вставленная в произвольную ячейку, выведет 1, строка =СТРОКА(А3) — цифру 3. 

Таким образом, при копировании формулы в следующую строку нумерация таблицы продолжится:

‘проставляем формулу нумерации

Range(«A7»).FormulaR1C1 = Range(«A6»).FormulaR1C1 

Если нужно также копировать формат ячейки, используется метод AutoFill.

Тут может возникнуть одна неприятность. Пусть наша последовательность ячеек с формулами начинается  не с первой строки, а например, с третьей. Тогда в третьей строке будет формула =Строка(А1), во второй — =Строка(А2), в 10 — =Строка(А10) и т.д. Тогда при удалении строки 6 формула в теперешней строке 9 выдаст ошибку «неверная ссылка». 

Это потому, что формула в строке А9 крайне смущена тем, что ссылается на удаленную ячейку. Поэтому если строки в таблице буду удаляться и добавляться, лучше сделать ссылку на ячейки другой страницы (=СТРОКА(Лист2!А1)).

Кнопки вставки и удаления строк

Также неочевидными оказались некоторые нюансы при вставке и удалении строк в таблице по нажатию на соответствующие кнопки (под таблицей будем понимать визуально выделенный  диапазон ячеек, содержащий связанные по смыслу данные). Например, у нас на листе есть две таблицы, у каждой есть кнопка «добавить строку». При добавлении для каждой строки появляется кнопка «удалить».

Само по себе добавление и удаление по имени кнопки сложности не представляет:

Private Sub InsertButton1_Click(position as Integer)
   ‘вставка строки перед строкой с номером position
   Rows(position).Insert
End Sub


Private Sub DeleteButton1_Click()
   Dim position as Integer
   ‘ ищем номер строки кнопки удаления
   position = _            ActiveSheet.Shapes(Application.Caller).TopLeftCell.Row  
   ‘ удаление кнопки
   ActiveSheet.Shapes(Application.Caller).Delete 
   ‘ удаление строки с номером position
   Rows(position).Delete
End Sub

Для нахождения позиции первой строки таблицы будем использовать именованные ячейки.

Но вот проблемка, которую по внимательности можно сразу и не разглядеть. Вот мы добавили некоторое количество строк с кнопками в обеих таблицах, потом поудаляли и снова добавили. Возникает ситуация, при которой у нас на листе появляются кнопки с одинаковым именем (т.к. они создавались на строке с одним и тем же номером). В связи с этим возникают проблемы при их удалении (удаляется последняя кнопка из всех с одинаковым именем).

Нам нужен уникальный идентификатор. Чтобы не заниматься генерацией уникальных хэшей, можно, например, использовать имяКнопки_номерСтроки_текущаяДата. 

newButtonId = «delButton» & insertedRowNumber & Now()

Маловероятно, что пользователь создаст за секунду более одной строки (в комплекте с кнопкой ее удаления) с одинаковым начальным номером строки.

Проверка листа на правильное заполнение 

Задача состоит в том, чтобы при сохранении файла проверять содержимое ячеек на всех листах и если какие-то помеченные как обязательные остались незаполненными, выдавать предупреждение пользователю. Для визуального выделения в зависимости от результата проверки содержимого ячеек на соответствие требованиям в excel можно использовать условное форматирование. Казалось бы, все просто: если мы используем условное форматирование и незаполненные ячейки (или неправильно заполненные, которые мы не смогли проверить при вводе с помощью меню «проверка данных») подкрашиваем, например, красным, то при сохранении все что нам нужно сделать — пройтись по всем ячейкам и проверить их цвет.

Но проблема вот в чем — если мы берем colorIndex или color ячейки, нам возвращается исходный цвет, не тот, на который он изменился при помощи условного форматирования.

В голову пришло два слегка костыльных способа решения (и честно говоря, если судить по форумам с обсуждением подобных проблем, кажется, что применительно к Excel по-другому их и не решишь).

Первый способ: в одном столбце, напротив каждой строки таблицы, формулой вычисляется, правильно ли заполнена строка. Тогда, проходясь по этому столбцу, мы можем сказать, в какой строке проблема. А при помощи условного форматирования проблемные ячейки могут подсвечиваться красным. Этого достаточно, если не надо точно знать, в какой ячейке проблема. При необходимости можно дальше обрабатывать эту строку по ячейкам. Способ хорош, если разные строки проверяются на разные условия (даже в рамках одной таблицы).

usedRows = ActiveSheet.UsedRange.Rows.Count
usedCols = ActiveSheet.UsedRange.Columns.Count
‘ переводим последний столбец из цифры в букву
usedColsInNumb = Split(Cells(1, usedCols).Address, «$»)(1)

For Each cell In ActiveSheet.Range(«A1:» & usedColsInNumb & usedRows).Cells

   ‘ если колонка с результатом формулы проверки заполнена

   If Len(cell.Value) > 0 Then 

       ‘ если строка неправильно заполнена

       If cell.Value = «ЛОЖЬ» Then 

            ‘ сохраняем в массив, отражающий правильность 
            ‘ заполнения каждой строки
            notFilled(cell.Row) = True 

       End If

   End If

Next

Второй способ: изначально ячейки, значения которых необходимо проверять, выделять цветом. Далее, проходясь по всем ячейкам, искать выделенные и проверять на соответствие условиям. Тут также при помощи условного форматирования проблемные ячейки могут подсвечиваться красным. Этот способ проще, если все ячейки проверяем на одни и те же условия, иначе надо вводить несколько цветов или как-то иначе метить ячейки. Например, при помощи именованных диапазонов для каждой области с одинаковой проверкой.

For Each cell In Sheets(i).Range(«A2:» & usedColsInNumb & usedRows).Cells

    ‘ проверяем выделенные цветом ячейки на пустоту

    If cell.Interior.Color = Sheets(5).Cells(1, 6).Interior.Color   And Len(cell.Value) = 0 Then

        ‘ обработка незаполненной ячейки

    End If

Next

Тут надо учитывать, что при использовании объединенных ячеек Excel искренне полагает, что содержимое находится в первой из них. Поэтому проверять на пустоту нужно только первую  ячейку из диапазона.

‘ ищем смежные с текущей ячейки в виде интервала, eg «A1:B10»

mergedInterv = Cells(cell.Row, cell.Column).MergeArea.Address(RowAbsolute:=False, ColumnAbsolute:=False)

‘ разбиваем адрес на первую и последнюю из смежных

splitAr = Split(mergedInt, «:»)

‘ если текущая ячейка входит в объединенные

If UBound(splitAr) = 1 Then 

      splitAr2 = Split(cell.Address, «$»)

      ‘ если первая из диапазона смежных равна текущей ячейке

      If splitAr(0) = splitAr2(1) & splitAr2(2) Then

          ‘ обработка незаполненной смежной ячейки

      End If

Else 

    ‘ если текущая ячейка не является смежной

End If

При нахождении последней используемой строки или столбца следует учесть, что если вы каким-то образом успели «поиспользовать» интервал (пусть даже выделили и очистили формат), то он все равно считается использованным. Придется удалить эти строки и столбцы.

Прилагаю демо-эксельку. Тестировалась в русифицированном MS Excel 2007.

Понравилась статья? Поделить с друзьями:
  • Нумерация колонок в excel цифрами
  • Нумерация колонок в excel буквы
  • Нумерация кириллицей в word
  • Нумерация заголовков word 2013
  • Нумерация заголовка word 2013