Обмен данными между формой и таблицей

Задача. Я хочу сделать ряд справок и страницу с константами. Одной из констант будет фамилия директора, которая используется в справках. При изменении этой константы фамилия в справке должна автоматически меняться. И я хочу менять фамилию из формы.

Создаем лист Константы и на нем ячейке даем имя.

И любое количество листов со справками. Ссылаясь на ячейку с фамилией.

Как вы понимаете, сколько я листов не создам, воспользовавшись ссылкой на ячейку =director, стоит мне изменить данные в ячейки с фамилией директора она везде поменяется. Это само нормально. Вот только менять я хочу из формы, например, чтобы с константами спрятать лист подальше от пользователя. Ну давайте создавать форму. Идем в редактор VBA:

При запуске формы мы должны прочитать данные с листа:

Private Sub UserForm_Activate() Worksheets.Item("Konst").Activate UserForm1.TextBox1.Text = Range("Director").TextEnd Sub

При нажатии на кнопку "Новый" заменить данные на листе константы (автоматически поменяются на справках):

Private Sub CommandButton2_Click() Range("Director").Value = UserForm1.TextBox1.TextEnd Sub

По нажатию на "Хватит" закрыть форму:

Private Sub CommandButton1_Click() Unload MeEnd Sub

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

 

Обработка ошибок VBA

Программирование это как хождение по минному полю. Неизвестно где взорвешься. Наверно так. Вы наслышаны о том, что Windows напичкан ошибками, о том что среда разработки любая при том - тоже. Мне попадались исследования на эту тему. Типа, что на каждые 1000 строк кода одна ошибка, у хорошего программиста естественно :-). В общем это закон такой. Все равно ошибешься где-нибудь. Проводя аналогию между женщиной и компьютером :-))) вообщем понятно.

Для обработки ошибок в VBA и VB есть специальный оператор On Error. Его задача при возникновении ошибки передать управление в то место( процедура или кусок кода), в котором это ждут. Посмотрим пример:

Sub Test() On Error GoTo Errors1 Dim x As Integer Dim a As Integer Dim c As Double x = 20 a = 0 c = x / a MsgBox (" Этого не должно быть") GoTo Ends:Errors1: MsgBox ("Ну ты блин Тикурила Даещь")Ends:End Sub

В данном примере при возникновении ошибки управление передается по метке Errors1 и дальше выполняется код. Я понимаю, что прерывать функцию из-за ошибки не всегда надо. И не только я так думаю, создатели VBA тоже так считали, и поэтому есть оператор Resume Next. Этот оператор реализует небезызвестный принцип - Ни шагу назад. Выполнение пойдет дальше, несмотря на ошибку.

Sub Test() On Error GoTo Errors1 Dim x As Integer Dim a As Integer Dim c As Double x = 20 a = 0 c = x / a MsgBox ("Опаньки !!!") GoTo Ends:Errors1: MsgBox ("Ну ты блин Тикурила Даещь") Resume NextEnds:End Sub

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

Sub Test() On Error Resume Next Dim x As Integer Dim a As Integer Dim c As Double x = 20 a = 0 c = x / a x = 10 a = 3 c = 10 / 3 MsgBox ("Опаньки !!!")End Sub

Над резюме можно немного поэкспериментировать, вот возможные описания:

Resume NextResune строкаResume меткаResume 0

 

Объект Err

Да, странное совпадение, 13 шаг и зловещий обьект Err, от которого одни неприятности. Этот обьект хранит информацию о последней ошибке в результате выполнения того, что вы запрограммировали. Ну давайте попробуем.

Sub Test() On Error GoTo Error1 Sheets.Item(1000).Delete GoTo EndsError1: MsgBox "Error detected" MsgBox (Str(Err.Number)) MsgBox (Err.Source) MsgBox (Err.Description)Ends:End Sub

Итак, Number - это номер ошибки Source, где она появилась, а Description описание. В данном случае Вам скажут о выходе за гарницу массива. Вот это здорово. Особенно при создании программ. Получить такое сообщение пользователю не очень приятно, а вот программисту : даже думать не надо.

У объекта Err есть метод очистки Clear, он все очишает. Вот в этом случае Вы не получите никаких сообщений. После обработки ошибки неплохо применить этот метод. Так, ради профилактики.

Sub Test() On Error GoTo Error1 Sheets.Item(1000).Delete GoTo EndsError1: Err.Clear MsgBox "Error detected" MsgBox (Str(Err.Number)) MsgBox (Err.Source) MsgBox (Err.Description)Ends:End Sub

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

ResumeExit Sub(Function)On Error

При отладке или специально в программе вы и сами можете сгенирировать ошибку методом Raise, только надо знать, что ошибки до 1000 зарезервированы VBA, а максимальный код 65535. Любое правило подвержено изменениям и поэтому есть специальная константа, от которой вы можете сложением получать коды ошибок. Она называется vbObjectError.

Sub Test() On Error GoTo Error1 Err.Raise 1001, "Test()", "Это я сделал"Error1: MsgBox "Error detected" MsgBox (Str(Err.Number)) MsgBox (Err.Source) MsgBox (Err.Description)Ends:End Sub

 

Задания на разработку

  1. Проделайте примеры, приведенные в лабораторной работе.
  2. Получите задание у преподавателя

Контрольные вопросы

1.

 

Литература

Каев Артем. http://www.firststeps.ru/vba/excel/vbaexcel1.html

 



/cgi-bin/footer.php"; ?>