Синтаксис VBA: ошибка выполнения 424 - требуется объект - PullRequest
1 голос
/ 28 мая 2020

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

Определенные переменные:

Sub UserForm_Initialize()
Call CloseButtonSettings(Me, False)
Dim selected_col As Long
Dim PZ_ID As Single, KD_ID As Single, Customer_Combination As String, Ship_ID As String, Author_ID As String, _
Art_Lager As Single, Art_Bestell As Single, DTPicker1 As Date, Calc_Time As Single, Time1 As Single, _
Time2 As Single, Time3 As Single, Time_Special As Single, Time_Total As Single, Notes_Buero As String, Notes_Lager As Single
End Sub

Поиск + Помещение данных в текстовые поля

  Private Sub CommandButton1_Click()
    Dim PZ_RNG As Range
    Dim strSearch As String

    strSearch = Packzettelinfo.PZ_ID
    Set PZ_RNG = Range("B:B").Find(strSearch, , xlValues, xlWhole)
    If Not PZ_RNG Is Nothing Then
    Else
        MsgBox "Packzettel Nr. " & strSearch & " konnte nicht gefunden werden (Fehler #001)", vbOKOnly
        Packzettelinfo.PZ_ID.SetFocus
    End If
    Range("E1") = PZ_RNG.Row 'Saving for later

Packzettelinfo.KD_ID = Cells(PZ_RNG.Row, PZ_RNG.Column + 1)
Packzettelinfo.Customer_Combination = Cells(PZ_RNG.Row, PZ_RNG.Column + 2)
Packzettelinfo.Ship_ID = Cells(PZ_RNG.Row, PZ_RNG.Column + 3)
Packzettelinfo.Author_ID = Cells(PZ_RNG.Row, PZ_RNG.Column + 4)
Packzettelinfo.Art_Lager = Cells(PZ_RNG.Row, PZ_RNG.Column + 5)
Packzettelinfo.Art_Bestell = Cells(PZ_RNG.Row, PZ_RNG.Column + 6)
Packzettelinfo.DTPicker1 = Cells(PZ_RNG.Row, PZ_RNG.Column + 7)
Packzettelinfo.Calc_Time = Cells(PZ_RNG.Row, PZ_RNG.Column + 8)
Packzettelinfo.Time1 = Cells(PZ_RNG.Row, PZ_RNG.Column + 10)
Packzettelinfo.Time2 = Cells(PZ_RNG.Row, PZ_RNG.Column + 11)
Packzettelinfo.Time3 = Cells(PZ_RNG.Row, PZ_RNG.Column + 12)
Packzettelinfo.Time_Special = Cells(PZ_RNG.Row, PZ_RNG.Column + 13)
Packzettelinfo.Time_Total = Cells(PZ_RNG.Row, PZ_RNG.Column + 14)
Packzettelinfo.Notes_Buero = Cells(PZ_RNG.Row, PZ_RNG.Column + 15)
Packzettelinfo.Notes_Lager = Cells(PZ_RNG.Row, PZ_RNG.Column + 16)
End Sub

Это отлично работает!

Но когда я пытаюсь сохранить текстовые поля (когда содержимое было изменено), появляется сообщение «Ошибка выполнения 424»:

Private Sub CB_PZ_save_edit_Click()
Cells(PZ_RNG.Row, PZ_RNG.Column + 1) = Packzettelinfo.KD_ID
Cells(PZ_RNG.Row, PZ_RNG.Column + 2) = Packzettelinfo.Customer_Combination
Cells(PZ_RNG.Row, PZ_RNG.Column + 3) = Packzettelinfo.Ship_ID
Cells(PZ_RNG.Row, PZ_RNG.Column + 4) = Packzettelinfo.Author_ID
Cells(PZ_RNG.Row, PZ_RNG.Column + 5) = Packzettelinfo.Art_Lager
Cells(PZ_RNG.Row, PZ_RNG.Column + 6) = Packzettelinfo.Art_Bestell
Cells(PZ_RNG.Row, PZ_RNG.Column + 7) = Packzettelinfo.DTPicker1
Cells(PZ_RNG.Row, PZ_RNG.Column + 8) = Packzettelinfo.Calc_Time
Cells(PZ_RNG.Row, PZ_RNG.Column + 10) = Packzettelinfo.Time1
Cells(PZ_RNG.Row, PZ_RNG.Column + 11) = Packzettelinfo.Time2
Cells(PZ_RNG.Row, PZ_RNG.Column + 12) = Packzettelinfo.Time3
Cells(PZ_RNG.Row, PZ_RNG.Column + 13) = Packzettelinfo.Time_Special
Cells(PZ_RNG.Row, PZ_RNG.Column + 14) = Packzettelinfo.Time_Total
Cells(PZ_RNG.Row, PZ_RNG.Column + 15) = Packzettelinfo.Notes_Buero
Cells(PZ_RNG.Row, PZ_RNG.Column + 16) = Packzettelinfo.Notes_Lager
End Sub

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

1 Ответ

1 голос
/ 28 мая 2020

Давайте сделаем шаг назад и посмотрим, что мы хотим сделать.

  1. Получить данные из диапазона в книге и заполнить их в текстовое поле пользовательской формы.
  2. Редактировать данные в пользовательской форме.
  3. Обновить новые данные обратно к рабочему листу.

Теперь мы можем сосредоточить наши усилия на этих трех шагах.

Но прежде чем мы перейдем к этому, вам будет полезно понять scope в VBA.

Теперь ваш код не самый наглядный (по крайней мере, не на английском sh), поэтому я собираюсь сделать несколько предположений, если это не поясняется в комментариях к вопросам.

Приведенное ниже написано в новой пользовательской форме с текстовым полем, меткой и 2 кнопками, все с именами по умолчанию (снимки экрана ниже).

Шаг 1:

Ваш метод для получить данные и поместить их в текстовое поле - это хорошо. Чтобы избежать двусмысленности, лучше всегда явно уточнять наши операторы, чтобы код смотрел на правильную книгу / рабочий лист или пользовательскую форму et c.

Private Sub CommandButton1_Click()

    Dim TargetCell As Range
    Dim SearchString As String
    SearchString = ThisWorkbook.Sheets("Sheet1").Range("A1").Value 'Only "Range("A1").Value" implies ActiveSheet which may give false results.

    Set TargetCell = ThisWorkbook.Sheets("Sheet1").Range("B:B").Find(SearchString, , xlValues, xlWhole)

    If Not TargetCell Is Nothing Then
        'TargetRange Is Something, do the thing
        'You could assign the values to the textbox here rather than outside of the If statement
        'Or you could change it to If TargetCell Is Nothing Then - And only execute the code in the Else section below
    Else
        MsgBox "Packzettel Nr. " & strSearch & " konnte nicht gefunden werden (Fehler #001)", vbOKOnly
        UserForm1.TextBox1.SetFocus
        Exit Sub    'This stops the rest of the code from running - I'm assuming the above is an error that nothing was found.
    End If

    ThisWorkbook.Sheets("Sheet1").Range("E1") = TargetCell.Address 'Saving for later

    UserForm1.TextBox1.Value = ThisWorkbook.Sheets("Sheet1").Cells(TargetCell.Row, TargetCell.Column).Offset(0, 1).Value

End Sub

Единственные реальные изменения, которые я внес в код, - это , где - Range или Cells, или что мы хотим получить доступ к Value свойство этого объекта.

Это и использование свойства Offset вместо + 1 et c. для колонн.

Шаг 2:

Пользователь изменяет данные по мере необходимости - нам нечего программировать.

Здесь вы можете добавить несколько шагов для проверки данных и т. Д. c.

Шаг 3:

Повторная запись данных обратно на лист, вы написали довольно хорошо. Опять же, я бы убедился, что объекты, такие как Range и Cells, явно квалифицируются с помощью соответствующей книги / рабочего листа и того, какое свойство мы хотим получить, например Value.

На этот раз я назначу книгу / лист переменной.

Private Sub CommandButton2_Click()

    Dim TargetSheet As Worksheet
    Set TargetSheet = ThisWorkbook.Sheets("Sheet1")
    Dim TargetCellAddress As String

    With TargetSheet
        TargetCellAddress = .Range("E1").Value  'Recall our saved cell address from the Commandbutton1 click
        .Range(TargetCellAddress).Offset(0, 1).Value = UserForm1.TextBox1.Value
        .Range("E1").ClearContents  'Remove TargetCellAddress value from the sheet
    End With

End Sub

Здесь в основном то же, что и выше, но в обратном порядке, но с использованием сохраненного свойства Range.Address из предыдущего (In E1).

Обратите внимание, что вы можете инкапсулировать свои операторы в With Statement, как я сделал с TargetSheet, таким образом вы можете получить доступ к его объектам, свойствам и методам без необходимости каждый раз уточнять их - хотя каждый оператор начинается с .


Подводя итог:

  • никакие переменные не нужно объявлять для любого из значений текстового поля, просто назначьте их непосредственно из / в пользовательскую форму / рабочий лист и наоборот.
  • Квалифицируйте ваши объекты и т.д. c. например, Range или Cells, и явно укажите, какое свойство вы хотите использовать, например Value (это по умолчанию, но не все!).

Вот несколько скриншотов при каждом нажатии.

Сначала открылась UserForm:
Sheet 1 with example data Userform 1 initialized

Нажата кнопка Command1:
Sheet1 after commandbutton1 is clicked UserForm after commandbutton1 is clicked

TextBox1 отредактировано:
Sheet1 after textbox is edited USerForm1 after textbox is edited

Commandbutton2 нажат:
Sheet1 after commandbutton2 is clicked UserForm1 after commandbutton2 is clicked

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...