2014-11-04 6 views
1

По какой-то причине мой код не работает. Я получаю сообщение «Ошибка 91». Я побежал это нормально с «Для каждого цикла, но это не работает для меня.Проблема с использованием цикла «For» в VBA

Это говорит мне отладить на

strPrint = MsgBox(prompt:="Print " & shtCurrent & "?", Buttons:=vbYesNo + vbExclamation) 

, но я не могу найти ничего плохого с ним.

Public Sub PrintWorksheets2() 

    'declare variables and assign address 
    Dim strPrint As String, intCount As Integer, wkbHours As Workbook, shtCurrent As Worksheet 
    Dim intSum As Integer, shtCount As Integer 
    Set wkbHours = Application.Workbooks("auco6215_HW10_Ex9.xlsm") 

    shtCount = wkbHours.Sheets.Count 
    intSum = 0 

    'ask user if he or she wants to print the worksheet 
    For intCount = 1 To shtCount 
     'shtCurrent = wkbHours 
     intSum = intSum + intCount 
     strPrint = MsgBox(prompt:="Print " & shtCurrent & "?", Buttons:=vbYesNo + vbExclamation) 
     If strPrint = vbYes Then  'if user wants to print 
      shtCurrent.PrintPreview 
     End If 
    Next intCount 

End Sub 
+0

Попробуйте объявить strPrint как вариант вместо строки. – bodjo

+0

Хорошо. Хотя, я объявил это как строку в моем цикле «Для каждого»? –

+2

@bodjo, хороший catch. Еще лучше будет 'VbMsgBoxResult'. –

ответ

0

Пожалуйста, попробуйте это.

'declare variables and assign address 
Dim strPrint As String, intCount As Integer, wkbHours As Workbook, shtCurrent As Worksheet 
Dim intSum As Integer, shtCount As Integer 
Dim oResult 
Set wkbHours = Application.Workbooks("auco6215_HW10_Ex9.xlsm") 

shtCount = wkbHours.Sheets.Count 
intSum = 0 

'ask user if he or she wants to print the worksheet 
For intCount = 1 To shtCount 
    'shtCurrent = wkbHours 
    intSum = intSum + intCount 
    oResult = MsgBox(prompt:="Print " & shtCurrent & "?", Buttons:=vbYesNo + vbExclamation) 
    If oResult = vbYes Then  'if user wants to print 
     shtCurrent.PrintPreview 
    End If 
Next intCount 
+0

У меня ошибка 91 все еще «Объектная переменная или с переменной блока не установлена». Это не нравится строка «vbResult = MsgBox (prompt: =« Print »& shtCurrent &«? », Buttons: = vbYesNo + vbExclamation« –

+0

Я не тестировал код. Но я изменил vbResult на oResult. shtCurrent - это тот, который вызывает ошибку, как упоминалось в @Ron. – bodjo

+0

Я дам это go. Каким должен быть тип данных, вариант? –

3

shtCurrent является Worksheet объект. Попробуйте кон catenating его свойство Name (который является String) в вашу MsgBox строку:

strPrint = MsgBox(prompt:="Print " & shtCurrent.Name & "?", Buttons:=vbYesNo + vbExclamation) 

Теперь strPrint объявлен как String:

Dim strPrint As String 

И MsgBox будет возвращать значение в vbMsgBoxResult перечислимого - вы делаете VBA делает много бесполезных неявных преобразований типов здесь, почему бы не объявить его как тип, который он возвращает?

Dim strPrint As vbMsgBoxResult 

И теперь вы видите, почему предваряя str к именам переменных (ака Венгерской нотации) плохо.


Это касается только части вопроса. Когда у вас был цикл For Each, каждая итерация присваивала значение переменной объекта, которая представляла рабочий лист текущей итерации. В этом коде с циклом For у вас есть рабочий лист shtCurrent, но он не назначен; вы увеличиваете счетчик, но это все, что вы делаете. Как было указано в комментариях, вам также необходимо указать Set ссылку на объект shtCurrent внутри цикла, до, который вы используете, иначе код будет взорван с ошибкой «ошибка объекта».

Ваших For петли индексов итерация рабочего лист, так что вы можете назначить shtCurrent к элементу в Worksheets коллекции:

Set shtCurrent = Worksheets(intCount) 

ли что, прежде чем что-нибудь еще в теле цикла For, и вы должны быть хорошо идти.

Теперь все хорошо, но когда вы повторяете объекты, часто лучше использовать цикл For Each вместо цикла For. For Петли хороши для итерации массивы; For Each Петли хороши для итерации коллекции - Я бы использовал петлю For Each здесь.

+0

Если объявить как Dim strPrint As String, и если мы проверим результат msgbox как это, если strPrint = vbYes Затем. Это все еще неуместно, и, как вы сказали, это сделает VBA для неявного преобразования типов для этого оператора тоже? –

+1

@PareshJadhav 'vbYes' является членом типа перечисления' VbMsgBoxResult' и имеет базовое 'Integer' значение '6' - в случае, когда вы описываете, когда пользователь нажимает кнопку« Да », результат вызова« MsgBox », хранящийся в' strPrint', будет преобразован в '" 6 "', чтобы сохранить результат в выделенной переменной String, а VB будет неявно конвертировать t 'vbYes' в свое' '6" 'строковое представление, прежде чем оно сравнивает его с' strPrint' в выражении 'if strPrint = vbYes' ... так что да. –

+0

Спасибо RetailCoder для объяснения. Последнее сомнение. Если мы объявляем переменную как VbMsgBoxResult, то требуется неявное преобразование или нет? –

Смежные вопросы