Страницы: 1
RSS
Действие при нажатии на кнопку "Отмена" и проверка, что вводимое значение "не пусто", в InputBox в ходе выполнения макроса
 
Здравствуйте!

Пробую написать макрос (см. ниже) для преобразования таблицы в нужный вид, но столкнулся с 2 проблемами. Уже 2 дня потратил на поиски решения здесь на форуме и в принципе на просторах интернета.
Порядок макроса такой, что:
1. определяются переменные;
2. активизируется диалоговое окно для выбора файла (с нужной таблицей для преобразования) пользователем;
3. далее пользователь должен указать диапазон таблицы, с которым работать;
4. ... указывается ячейка, кол-во столбцов, наименование для каждого столбца и наименование столбца со значением (каждый раз через InputBox);
5. далее идет процесс преобразования диапазона согласно заданным условиям (его уже в коде не указывал).

Так вот, при 1-м InputBox для указания диапазона, если пользователь нажимает кнопка "Отмена" макрос прерывается и выдает ошибку, аналогично для 2-го InputBox для выбора ячейки.
Для последующих InputBox, т.к. они не объекты, а значения, то просто использую проверку на False с If (эквивалентно нажатию на кнопку "Отмена"). Все работает корректно.
Чтобы при нажатии на кнопку "Отмена" в 1-м и 2-м InputBox макрос выдавал сообщение и заканчивал работу попробовал использовать On Error GoTo. Однако все бы ничего, но теперь при последнем InputBox (str2 = Application.InputBox(Prompt:="наименование столбца со значением", Title:="Укажите...", Type:=2)) независимо от того, ввожу я наименование или нажимаю "Отмена", выдается сообщение и макрос закрывается. Однако в случае ввода наименования все должно корректно работать, и начинаться процесс преобразования. Вот в этом и состоит проблема, может есть возможность ее решить?

Так же еще не получается сделать (как я думаю здесь нужен цикл) проверку на то, что пользователь не вводит наименования столбца и далее столбца со значением.
Вот, например, здесь
Код
str2 = Application.InputBox(Prompt:="наименование столбца со значением", Title:="Укажите...", Type:=2)
If str2 = False Then
'Вывод информационного окна с сообщением при нажатии кнопки "Отмена"
MsgBox "Отмена преобразования данных!", vbCritical, "Информационное сообщение"
Exit Sub
End If
Т.е. если наименование не вводится пользователем, который при этом нажимает кнопку "Ок", должно выводиться сообщение, что такое название необходимо ввести, и снова отображаться InputBox для введения наименования. Такое возможно сделать?


Код
Sub ConvertData()

Dim FName As Variant
Dim r As Range
Dim r2 As Range
Dim r3 As Range
Dim z As Long
Dim N As Integer
Dim Hold As Variant
Dim wb As Workbook
Dim ws As Worksheet
Dim ColNum As Integer
Dim i As Long
Dim k As Long
Dim j As Long
Dim l As Long
Dim str As String
Dim str2 As String
Dim QC As Integer

FName = Application.GetOpenFilename(FileFilter:="Excel Workbooks,*.xl*", Title:="Выберите файл, который надо открыть", MultiSelect:=False)
If FName <> False Then
Workbooks.Open Filename:=FName
End If

On Error GoTo Inform
Set r3 = Application.InputBox(Prompt:="Диапазон:", Title:="Выберете диапазон ячеек", Type:=8)
r3.Select

Set r = r3

Set r2 = Application.InputBox(Prompt:="ячейку, с которой необходимо начать преобразование:", Title:="Выберете...", Type:=8)

QC = Application.InputBox(Prompt:="количество столбцов:", Title:="Укажите...", Type:=1)
If QC = False Then
'Вывод информационного окна с сообщением при нажатии кнопки "Отмена"
MsgBox "Отмена преобразования данных!", vbCritical, "Информационное сообщение"
Exit Sub
End If

ReDim strarr(QC)
For i = 1 To QC
strarr(i) = Application.InputBox(Prompt:="наименование столбца " & CStr(i), Title:="Укажите...", Type:=2)
If strarr(i) = False Then
'Вывод информационного окна с сообщением при нажатии кнопки "Отмена"
MsgBox "Отмена преобразования данных!", vbCritical, "Информационное сообщение"
Exit Sub
End If
Next i

str2 = Application.InputBox(Prompt:="наименование столбца со значением", Title:="Укажите...", Type:=2)
If str2 = False Then
'Вывод информационного окна с сообщением при нажатии кнопки "Отмена"
MsgBox "Отмена преобразования данных!", vbCritical, "Информационное сообщение"
Exit Sub
End If


'..........
'..........
'Здесь идет код по преобразованию таблицы в нужный вид (не так важно уже)
'..........
'..........


Inform:
'Вывод информационного окна с сообщением об ошибке (при нажатии кнопки "Отмена")
MsgBox "Отмена преобразования данных!", vbCritical, "Информационное сообщение"
Exit Sub

End Sub
Изменено: bond_0790 - 17.01.2022 11:46:03
 
Код
Do
    str2 = Application.InputBox(Prompt:="наименование столбца со значением", Title:="Укажите...", Type:=2)
    If str2 <> "" Then Exit Do
    MsgBox "такое название необходимо ввести", vbCritical, "Информационное сообщение"
    If str2 = False Then
    'Вывод информационного окна с сообщением при нажатии кнопки "Отмена"
    MsgBox "Отмена преобразования данных!", vbCritical, "Информационное сообщение"
    Exit Sub
    End If
Loop
 
Добрый день!

А по inputbox для диапазонов наверное так можно обработать: нет - так два раза инпутбокс выводится...
Код
If TypeName(Application.InputBox(Prompt:="Диапазон:", Title:="Выберете диапазон ячеек", Type:=8)) = "Range" Then
    Set r3 = Application.InputBox(Prompt:="Диапазон:", Title:="Выберете диапазон ячеек", Type:=8)
    r3.Select
Else
    Exit Sub
End If
Изменено: webley - 17.01.2022 12:40:29
 
А вот так пожалуй получится. Надо результат каждого InputBox сначала в переменную variant помещать и проверять ее тип - если boolean, значит нажали отмену (справедливо и для строк и для диапазонов):
Код
Dim InputBoxResult As Variant

InputBoxResult = Application.InputBox(Prompt:="Диапазон:", Title:="Выберете диапазон ячеек", Type:=8)
If TypeName(InputBoxResult) = "Boolean" Then
    MsgBox "Отмена преобразования данных!", vbCritical, "Информационное сообщение"
    Exit Sub
Else
    Set r3 = InputBoxResult 
    r3.Select
End If
Изменено: webley - 17.01.2022 13:02:32 (Тоже при тщательной проверки не работает)
 
bond_0790, Работа с диалогами
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
МатросНаЗебре, не совсем Вас понял.
При этой конструкции при нажатии "Отмена" просто идет дальнейшее выполнение макроса, в то время, как должно происходить его завершение и еще проверка на пустое (не введенное) значение.
Изменено: bond_0790 - 17.01.2022 13:50:36
 
Код
Do
    str2 = Application.InputBox(Prompt:="наименование столбца со значением", Title:="Укажите...", Type:=2)
    
    If str2 = False Then
        'Вывод информационного окна с сообщением при нажатии кнопки "Отмена"
        MsgBox "Отмена преобразования данных!", vbCritical, "Информационное сообщение"
        Exit Sub
    End If
    
    If str2 <> "" Then Exit Do
    MsgBox "такое название необходимо ввести", vbCritical, "Информационное сообщение"
Loop
 
МатросНаЗебре, в последней версии Вашего кода Вы поменяли местами условия. В таком случае при нажатии на кнопку Отмена макрос да прекращает работу, сообщение при этом выводится.
При нажатии на Ок (неважно - при незаполненной (пустой) или заполненной строке) появляется ошибка "Несоответствие типов". Вот в этом-то вся и проблема и в другим решениях, которые пробовал.

Тестировал уже только эту часть в отдельном макросе.

Изменено: bond_0790 - 17.01.2022 17:57:56
 
Jack Famous, благодарю Вас за ссылку!
Изучил, вот что получается, например (может кому пригодится):
Код
On Error Resume Next
Set r3 = Application.InputBox(Prompt:="Диапазон:", Title:="Выберете диапазон ячеек", Type:=8)
If r3 Is Nothing Then 'нажата кнопка "Отмена"
MsgBox "Отмена выполнения операции!", vbCritical, "Информационное сообщение"
Exit Sub 'завершаем процедуру, т.к. ячейки не выбраны
End If

В случае нажатия кнопки Отмена макрос перестает выполняться с выводом соответствующего сообщения.

Jack Famous,может Вы еще подскажите, как быть в этих случаях - чтобы при отмене также выводилось сообщение, а при нажатии кнопки Ок без ввода текста снова сообщение (другое) о необходимости ввести наименование и возврат на форму ввода???

Пошел путем, как МатросНаЗебре предлагал.

Здесь все работает как надо:

Код
ReDim strarr(QC)
For i = 1 To QC
Do
strarr(i) = Application.InputBox(Prompt:="наименование столбца " & CStr(i), Title:="Укажите...", Type:=2)
If strarr(i) = False Then
'Вывод информационного окна с сообщением при нажатии кнопки "Отмена"
MsgBox "Отмена выполнения операции!", vbCritical, "Информационное сообщение"
Exit Sub
End If
If strarr(i) <> "" Then Exit Do
MsgBox "Необходимо ввести наименование столбца!", vbCritical, "Информационное сообщение"
Loop

Здесь же не хочет работать:
Код
Dim str2 As String

Do
str2 = Application.InputBox(Prompt:="наименование столбца со значением", Title:="Укажите...", Type:=2)
If str2 = False Then
'Вывод информационного окна с сообщением при нажатии кнопки "Отмена"
MsgBox "Отмена выполнения операции!", vbCritical, "Информационное сообщение"
Exit Sub
End If
If str2 <> "" Then Exit Do
MsgBox "Необходимо ввести наименование столбца!", vbCritical, "Информационное сообщение"
Loop

Если честно, совсем не понимаю, в чем тут нестыковка.  :(  
Изменено: bond_0790 - 17.01.2022 17:57:20
 
Цитата
написал:
в чем тут нестыковка
по ссылке я вроде все расписывал. Вы просто смотрели исключительно на Application.Inputbox, но если нужен просто текст, то нет смысла в Application.Inputbox, можно использовать простой:
Код
Dim str2
str2 = InputBox("наименование столбца со значением:", "Запрос данных")
'Если нажата кнопка Отмена
If StrPtr(str2) = 0 Then
    MsgBox "Нажата кнопка Отмена. Процедура прервана", vbCritical, "www.excel-vba.ru"
    Exit Sub
End If
однако, если речь про название столбца, то лучше запрашивать номер. И такой пример тоже приводится:    
Код
    Dim vRetVal 'для получения выбранного значения
    vRetVal = InputBox("Укажите номер столбца для удаления(целое число):", "Запрос данных", 5)
    'используем Val для преобразования текста vRetVal в число
    'Val() преобразует число как текст в число.
    'Если указан текст(например "третий") - он будет преобразован в 0
    vRetVal = Val(vRetVal)
    If Val(vRetVal) = 0 Then
        MsgBox "Номер столбца должен быть целым числом больше нуля!", vbCritical, "DelCols"
        Exit Sub
    End If

Цитата
bond_0790 написал:
в чем тут нестыковка
потому что переменную объявляете как текстовую:
Код
Dim str2 As String

а сравнивать её пытаетесь с булевым значением. Но она никогда не будет равна False, в лучшем случае - "False"
Изменено: Дмитрий(The_Prist) Щербаков - 17.01.2022 18:05:18
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Дмитрий(The_Prist) Щербаков, сравнение срабатывает при заключении False в кавычки, т.е.
Код
Dim str2 As String

Do
str2 = Application.InputBox(Prompt:="наименование столбца со значением", Title:="Укажите...", Type:=2)
If str2 = "False" Then
'Вывод информационного окна с сообщением при нажатии кнопки "Отмена"
MsgBox "Отмена выполнения операции!", vbCritical, "Информационное сообщение"
Exit Sub
End If
If str2 <> "" Then Exit Do
MsgBox "Необходимо ввести наименование столбца!", vbCritical, "Информационное сообщение"
Loop
Также учту Ваши комментарии.

Еще раз большое спасибо всем за отзывчивость и помощь!  :)
Успехов всем!  ;)  
Изменено: bond_0790 - 17.01.2022 18:24:43
Страницы: 1
Наверх