Home » excel » excel vba – Issue using "For" loop in VBA

excel vba – Issue using "For" loop in VBA

Posted by: admin May 14, 2020 Leave a comment

Questions:

For some reason my code is not working. I am getting “Error 91”. I ran it fine with a “For each loop but this is not working for me.

It is telling me to debug at

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

but I cannot find anything wrong with it.

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
How to&Answers:

shtCurrent is a Worksheet object. Try concatenating its Name property (which is a String) into your msgbox prompt:

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

Now strPrint is declared as a String:

Dim strPrint As String

And MsgBox will return a vbMsgBoxResult enum value – you’re making VBA do lots of useless implicit type conversions here, why not declare it as the type it’s returned as?

Dim strPrint As vbMsgBoxResult

And now you see why prefixing str to variable names (aka Hungarian notation) is bad.


That only addresses part of the issue. When you had a For Each loop, each iteration assigned a value to an object variable that represented the current iteration’s worksheet. In this code with a For loop, you have a shtCurrent worksheet object, but it’s not assigned; you’re incrementing a counter, but that’s all you’re doing. As was hinted in the comments, you also need to Set the reference for the shtCurrent object inside the loop, before you use it – otherwise your code will blow up with an “object variable not set” error.

Your For loop iterates worksheet indices, so you can assign shtCurrent to an item in the Worksheets collection:

Set shtCurrent = Worksheets(intCount)

Do that before anything else inside the body of the For loop, and you should be good to go.

Now that’s all nice, but when you’re iterating objects, it’s often better to use a For Each loop instead of a For loop. For loops are good for iterating arrays; For Each loops are good for iterating collections – I’d use a For Each loop here.

Answer:

Please try this.

'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