Пробую написать макрос (см. ниже) для преобразования таблицы в нужный вид, но столкнулся с 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
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
А вот так пожалуй получится. Надо результат каждого 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(Тоже при тщательной проверки не работает)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
МатросНаЗебре, не совсем Вас понял. При этой конструкции при нажатии "Отмена" просто идет дальнейшее выполнение макроса, в то время, как должно происходить его завершение и еще проверка на пустое (не введенное) значение.
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
МатросНаЗебре, в последней версии Вашего кода Вы поменяли местами условия. В таком случае при нажатии на кнопку Отмена макрос да прекращает работу, сообщение при этом выводится. При нажатии на Ок (неважно - при незаполненной (пустой) или заполненной строке) появляется ошибка "Несоответствие типов". Вот в этом-то вся и проблема и в другим решениях, которые пробовал.
Тестировал уже только эту часть в отдельном макросе.
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
Если честно, совсем не понимаю, в чем тут нестыковка.
по ссылке я вроде все расписывал. Вы просто смотрели исключительно на 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
Дмитрий(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
Также учту Ваши комментарии.
Еще раз большое спасибо всем за отзывчивость и помощь! Успехов всем!