Страницы: 1
RSS
Обработки ошибок в VBA (двойное On Error GoTo)
 
Ночи доброй всем!
Ругается на код, где я использую двойную проверку на ошибки, вот часть макроса (копирование листа из другой книги с использованием UserForms):
Код
Public List
           With ActiveWorkbook
 On Error GoTo Error1
           Call List_copy ' выполняется Активация User формы, где из сплывающего списка необходимо выбрать название листа, который нужно копировать

           .Sheets(List).Copy before:=BazaWb.Sheets(1)
 GoTo Ends:
 Error1:
 On Error GoTo Error2
            List = InputBox("Данный лист не найден, введите название листа вручную", "IO", "")
            .Sheets(List).Copy before:=BazaWb.Sheets(1)
 GoTo Ends:
 Error2:
 MsgBox ("Дынный лист не найден, проверьте правильность написания и повторите процедуру") Exit Sub '? здесь процедуру заканчивать 
 Ends:
          End With
  
           Workbooks(oAwb).Close False    'Закрываем книгу

И вот здесь у меня ругается на 11 строку. Вроде на мой (любительский) взгляд правильно. Может грамматика? подскажите
Изменено: slesarok - 11.12.2017 23:05:45 (Добавил тестовый Файл)
 
Простите, на 11 строчку ругается
Изменено: slesarok - 11.12.2017 22:15:06
 
Переменные типа Public объявляются ВНЕ процедур, в самом верху модуля (область объявлений называется)
Согласие есть продукт при полном непротивлении сторон
 
Да, это я написал, что она задана... в самом начале кода, а не именно в этом месте..
Может нельзя использовать 2 раза в одном коде On Error GoTo?
Изменено: slesarok - 11.12.2017 21:54:49 (Поправки)
 
я написал не 'вначале кода', а ВНЕ всех процедур (кодов)
ЧТО ТАКОЕ ПЕРЕМЕННАЯ И КАК ПРАВИЛЬНО ЕЁ ОБЪЯВИТЬ?
Согласие есть продукт при полном непротивлении сторон
 
Восьмая строка, девятая... Не нужно вручную нумеровать строки - движок форума сам их пронумерует, а у Вас из-за этого получилась двойная нумерация. Исправьте код.
 
 А какими словами 'ругается'? Что в переменной List в момент ошибки?
Согласие есть продукт при полном непротивлении сторон
 
Sanja может я неправильно выразился, переменная объявлена вне процедуры, в коде я её просто написал сейчас, для информативности, что она задана и не в этом ошибка!
Извиняюсь, я только начинаю изучать VBA много вопросов, которые не под силу пока что самостоятельно решить)
 
Это я уже понял. См. вопросы выше
Согласие есть продукт при полном непротивлении сторон
 
Если описать слови код, то будет так:
1. При начале процедуры открывается окно, где нужно выбрать файл, откуда копировать лист
2. После выбора файла вызывается List_copy (Это UserForm) так 6 кнопок и типовыми названиями листов (например Лист1, Лист2, Лист3 и тд)
3. При выборе Листа, которого макрос не нашел в этом файле предлагается ввести название листа вручную, вызывая InputBox
Вот до этого момента у меня все работало, но я решил еще добавить сообщение, при неправильном ручном вводе Листа и завершить процедуру...
Тут я и залип)
 
На счет нумерации я уже понял, когда написал, впредь не буду!
Ошибка:
Код
Run-time Error '9'
Subscript out ofrange
 
Цитата
slesarok написал:
впредь не буду!
СЕЙЧАС исправьте.
 
Юрий М - уже исправил
Sanja - в переменной List вводится значение руками, если я введу Лист который есть (например Лист1), то процедура завершиться блогополучно, а если я ошибусь и введу данные неверные (наример Лист111) но данная ошибка
 
Нужно в данном случае не обрабатывать ошибку, а не допускать её: проверить наличие такого листа.
 
Вот создал из части кода отдельный файлик.
Посмотрите пожалуйста
 
Никто не поможет?(
 
Заполняйте список на форме существующими в открытой книге листами:
Код
With UserForm1
.ComboBox1.Clear
For Each sh In ActiveWorkbook.Worksheets
.ComboBox1.AddItem (sh.Name)
Next sh
 
Код
Option Explicit

Public list

Sub asdf()
'какой-то код
With ActiveWorkbook
  On Error Resume Next 'и тут мы решили попроверять ошибки
  Call List_copy
  .Sheets(list).Copy before:=.Sheets(1) 'вот здесь предполагается ошибка
  If Err Then 'если err<>0, значит ошибка есть
    Stop 'вот здесь Вы можете выделив "err", нажать прав. кн. мышки и в контекстном меню "Add Watch"
    MsgBox Err.Description & vbCrLf _
      & "Ошибка N " & Err.Number 'внизу в табл. "Watches" увидите err и его структуру
    list = InputBox("Данный лист не найден, введите название листа вручную", "IO", "")
    Err = 0 'сбрасываем ошибку, чтоб узнать появится ли она снова
    .Sheets(list).Copy before:=.Sheets(1) 'вот здесь опять предполагается ошибка
    If Err Then 'если err<>0, значит опять ошибка есть
      MsgBox ("Дынный лист не найден, проверьте правильность написания и повторите процедуру")
      Exit Sub
    End If
  End If
  On Error GoTo 0 'прекращаем обработку ошибок
  'дальнейший правильный код не предполагающий ошибок
End With
End Sub

Вот еще вариант касаемо листов:
Код
Function ShEx(shNm) As Boolean
On Error Resume Next
ShEx = Not Sheets(shNm) Is Nothing
End Function

Sub Test
If ShEx("Не знаю какое имя листа") Then
  msgbox "Надо же, такой лист есть!"
Else
  msgbox "Листа с таким именем не существует..."
End Sub

Sub asdf()
'какой-то код
With ActiveWorkbook
  If ShEx(list) Then
    .Sheets(list).Copy before:=.Sheets(1)
  Else
    list = InputBox("Данный лист не найден, введите название листа вручную", "IO", "")
    If ShEx(list) Then
      .Sheets(list).Copy before:=.Sheets(1)
    Else
      MsgBox ("Дынный лист не найден, проверьте правильность написания и повторите процедуру"): Exit Sub
    End If
  End If
  'дальнейший код
End With
End Sub
Изменено: AAF - 12.12.2017 07:45:19
 
Немного переделал макрос. Что касаемо формы, во избежание набора имени листа вручную, можно на форме сделать ComboBox, который собирал бы в себе список всез листов открываемой книги. Соответственно в ComboBox выбираем из списка нужный лист, и "вуаля" он перенесен в основную книгу. Вот как-то так.
"Все гениальное просто, а все простое гениально!!!"
 
AAF - спасибо, понял про ошибки их правильное написание в этом примере!
k61 - про это мне надо было заранее подумать, чтобы не перебирать вручную листы, идея отличная!
Nordheim - посмотрел файл, все работает на ура! Только зацикливается, если не можешь правильно ввести лист, или просто захочешь выйти из этой процедуры)
Парни, а поможете реализовать это в UserForm в Виде ListBox - чтобы найденные на книге листы как списком отображались, на выбранный нажимаешь и он копируется?

Сейчас конечно буду пробовать сам... но так как я только учусь, то вопросов еще много у меня будет)))
Изменено: slesarok - 12.12.2017 17:22:54
 
В коде от k61, замените ComboBox1 на ListBox1.
Согласие есть продукт при полном непротивлении сторон
 
В UserForm прописал:
Код
Private Sub UserForm1_Initialize()
With ListBox1
.ListBox1.Clear
For Each sh In ActiveWorkbook.Worksheets
.ListBox1.AddItem (sh.Name)
Next sh
End Sub

Вылезает пустая форма (список)  :(  
Изменено: slesarok - 12.12.2017 17:55:02
 
Код
Private Sub UserForm_Initialize()
With Me.ListBox1
    .Clear
    For Each sh In ActiveWorkbook.Worksheets
        .AddItem (sh.Name)
    Next sh
End With
End Sub
Согласие есть продукт при полном непротивлении сторон
 
Посмотрите файл-пример, может чем пригодится
Согласие есть продукт при полном непротивлении сторон
 
Sanja - спасибо большой! Буду доделывать)
Страницы: 1
Наверх