MyName
MyName

Reputation: 370

select method of range .cells fails on 2nd go

I've been working on the code below for a while now and I'm almost done. It's taking 3 cells of data from one sheet, copying it in another, saving a copy based on the name in the first sheet and then looping until completed for all filled rows.

The snag I'm hitting is that when the first loop completes and it needs to select the WB that holds the data (the selection is needed for the function) it can't select it due to a fault in WsStam.Cells(row, iKolomnrCorpID).EntireRow.Select. When I debug, switch to the WB and run code it does work. It's probably something stupid I'm missing. I appreciate your help!

Sub motivatieFormOpmaken()

        Dim wbMotivTemp As Workbook
        Dim wsMotiv As Worksheet
        Dim PathOnly, mot, FileOnly As String
        Dim StrPadSourcenaam As String
        Dim WsStam As Worksheet
        Dim WbStam As Workbook
        Dim LastRow As Long

    Set wbMotivTemp = ThisWorkbook
    Set wsMotiv = ActiveSheet

    StrHoofdDocument = ActiveWorkbook.Name
    StrPadHoofdDocument = ActiveWorkbook.Path
    StrPadSourcenaam = StrPadHoofdDocument & "\" & c_SourceDump

    If Not FileThere(StrPadSourcenaam) Then
       MsgBox "Document " & StrPadSourcenaam & " is niet gevonden."
    Exit Sub
    End If

    Application.ScreenUpdating = False

    Workbooks.Open FileName:=StrPadSourcenaam
    Set WbStam = ActiveWorkbook
    Set WsStam = WbStam.Worksheets("Stambestand")
    Application.Run "Stambestand.xlsm!unhiderowsandcolumns"
    Worksheets("stambestand").Activate

    iLaatsteKolom = Worksheets("stambestand").Cells.SpecialCells(xlLastCell).Column
    iLaatsteRij = Worksheets("stambestand").Cells.SpecialCells(xlLastCell).row

    VulKolomNr
    If KolomControle = False Then Exit Sub

    Cells(1, iKolomnrVerwijderen_uit_de_tellingen).AutoFilter Field:=iKolomnrVerwijderen_uit_de_tellingen, Criteria1:="0"
    LastRow = Cells(1, iKolomnrCorpID).End(xlDown).row

    Dim row As Long
    row = 2
    With WsStam
        Do Until row > iLaatsteRij
            If .Cells(row, iKolomnrCorpID).RowHeight > 0 Then
                WsStam.Cells(row, iKolomnrCorpID).EntireRow.Select 'It crashes at this line, after the first loop
                wsMotiv.Range("motiv_cid") = Cells(row, iKolomnrCorpID).Text
                wsMotiv.Range("motiv_naam") = Cells(row, iKolomnrNaam).Text
                wsMotiv.Range("motiv_ldg") = Cells(row, iKolomnrHuidigeLeidingGevende).Text
                n = naamOpmaken
                wbMotivTemp.Activate
                ActiveWorkbook.SaveAs FileName:=StrPadHoofdDocument & "\Docs\" & n & ".xlsm", FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False
            End If
            row = row + 1
        Loop
    End With

End Sub

Function naamOpmaken() As String
    Dim rng As Range
    Dim row As Range
    Set rng = Selection.SpecialCells(xlCellTypeVisible)

    iRijnummer = rng.row
        If iRijnummer > 1 Then
            naam = Cells(iRijnummer, iKolomnrNaam).Text
            ldg = Cells(iRijnummer, iKolomnrHuidigeLeidingGevende).Text
            cid = Cells(iRijnummer, iKolomnrCorpID).Text

            Dim Position As Long, Length As Long
            Dim n As String
            Position = InStrRev(naam, " ")
            Length = Len(naam)
            n = Right(naam, Length - Position)
        End If
    naamOpmaken = n + "-" + ldg + "-" + cid
End Function

Upvotes: 0

Views: 38

Answers (2)

Darren Bartrup-Cook
Darren Bartrup-Cook

Reputation: 19782

Hopefully you may find this useful for the future.

I've had a look through your code and made some updates so you shouldn't have to select any sheets and that problem line is removed completely. I've also added a new function at the bottom which will find the last cell on any sheet you reference.

Option Explicit  'Very important at top of module.
                 'Ensures all variables are declared correctly.

Sub motivatieFormOpmaken()

    Dim wbMotivTemp As Workbook
    Dim wsMotiv As Worksheet
'    Dim PathOnly, mot, FileOnly As String

    '''''''''''''''''''
    'New code.
    Dim PathOnly As String, mot As String, FileOnly As String
    '''''''''''''''''''

    Dim StrPadSourcenaam As String

    '''''''''''''''''''
    'New code.
    Dim StrHoofdDocument As String
    Dim StrPadHoofdDocument As String
    Dim c_SourceDump As String
    c_SourceDump = "MyFileName.xlsx"
    Dim KolomControle As Boolean
    '''''''''''''''''''


    Dim WsStam As Worksheet
    Dim WbStam As Workbook
    Dim LastRow As Long

    Set wbMotivTemp = ThisWorkbook
    Set wsMotiv = ActiveSheet

    StrHoofdDocument = ActiveWorkbook.Name
    StrPadHoofdDocument = ActiveWorkbook.Path
    StrPadSourcenaam = StrPadHoofdDocument & "\" & c_SourceDump

    If Not FileThere(StrPadSourcenaam) Then
       MsgBox "Document " & StrPadSourcenaam & " is niet gevonden."
    Else
'    Exit Sub
'    End If

        Application.ScreenUpdating = False

'        Workbooks.Open Filename:=StrPadSourcenaam
'        Set WbStam = ActiveWorkbook

        '''''''''''''''''''
        'New code.
        Set WbStam = Workbooks.Open(Filename:=StrPadSourcenaam)
        '''''''''''''''''''

        Set WsStam = WbStam.Worksheets("Stambestand")
'        Application.Run "Stambestand.xlsm!unhiderowsandcolumns"

        '''''''''''''''''''
        'New code as possible replacement for "unhiderowsandcolumns"
        WsStam.Cells.EntireColumn.Hidden = False
        WsStam.Cells.EntireRow.Hidden = False
        '''''''''''''''''''

'        Worksheets("stambestand").Activate

'        iLaatsteKolom = Worksheets("stambestand").Cells.SpecialCells(xlLastCell).Column
'        iLaatsteRij = Worksheets("stambestand").Cells.SpecialCells(xlLastCell).row

        '''''''''''''''''''
        'New code.  You may want to check for filters before finding last row?
        iLaatsteKolom = LastCell(WsStam).Column
        iLaatsteRij = LastCell(WsStam).row
        '''''''''''''''''''

        VulKolomNr 'No idea - getting deja vu here.
'        If KolomControle = False Then Exit Sub

        '''''''''''''''''''
        'New code.
        If KolomControle Then
        '''''''''''''''''''

            WsStam.Cells(1, iKolomnrVerwijderen_uit_de_tellingen).AutoFilter Field:=iKolomnrVerwijderen_uit_de_tellingen, Criteria1:="0"
'            LastRow = Cells(1, iKolomnrCorpID).End(xlDown).row

            '''''''''''''''''''
            'New code.  The function will return the last filtered row.
            LastRow = LastCell(WsStam).row
            '''''''''''''''''''

            Dim row As Long
            row = 2
            With WsStam
                Do Until row > iLaatsteRij
                    If .Cells(row, iKolomnrCorpID).RowHeight > 0 Then
'''''''''''''''''''
'I don't think you even need this line.
'                        WsStam.Cells(row, iKolomnrCorpID).EntireRow.Select 'It crashes at this line, after the first loop
'                        wsMotiv.Range("motiv_cid") = Cells(row, iKolomnrCorpID).Text
'                        wsMotiv.Range("motiv_naam") = Cells(row, iKolomnrNaam).Text
'                        wsMotiv.Range("motiv_ldg") = Cells(row, iKolomnrHuidigeLeidingGevende).Text

                        '''''''''''''''''''
                        'New code.  Note the "." before "Cells" which tells it that cell is on "WsStam" (in the "With")
                        '           Also formatting the cell to text - will need to update as required.
                        wsMotiv.Range("motiv_cid") = Format(.Cells(row, iKolomnrCorpID), "0000")
                        wsMotiv.Range("motiv_naam") = Format(.Cells(row, iKolomnrNaam), "0000")
                        wsMotiv.Range("motiv_ldg") = Format(.Cells(row, iKolomnrHuidigeLeidingGevende), "0000")

'Do you mean this to save on each loop?
'                        n = naamOpmaken
'                        wbMotivTemp.Activate
'                        ActiveWorkbook.SaveAs Filename:=StrPadHoofdDocument & "\Docs\" & n & ".xlsm", FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False

                        '''''''''''''''''''
                        'New code.  Combines the above three lines.
                        wbMotivTemp.SaveAs Filename:=StrPadHoofdDocument & "\Docs\" & naamOpmaken(WsStam) & ".xlsm", FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False

                    End If
                    row = row + 1
                Loop
            End With

        '''''''''''''''''''
        'New code. End of "If KolomControle" block.
        End If
        '''''''''''''''''''

    ''''''''''''''''
    'New code - end of "If Not FileThere" block.
    'Give procedure a single exit point.
    End If

End Sub

'Added the worksheet as an argument to the procedure.
'This is then passed from the main procedure and you don't need to select the sheet first.
Function naamOpmaken(wrkSht As Worksheet) As String
    Dim rng As Range
    Dim row As Range
    Set rng = Selection.SpecialCells(xlCellTypeVisible)

    '''''''''''''''''''
    'New code
    Dim naam As String
    Dim ldg As String
    Dim cid As String
    '''''''''''''''''''

    iRijnummer = rng.row
        If iRijnummer > 1 Then

'            naam = Cells(iRijnummer, iKolomnrNaam).Text
'            ldg = Cells(iRijnummer, iKolomnrHuidigeLeidingGevende).Text
'            cid = Cells(iRijnummer, iKolomnrCorpID).Text

            '''''''''''''''''''
            'New code - not reference to the worksheet, and using default value of cell.
            '           may need to add "FORMAT" to get numericals in correct format.
            naam = wrkSht.Cells(iRijnummer, iKolomnrNaam)
            ldg = wrkSht.Cells(iRijnummer, iKolomnrHuidigeLeidingGevende)
            cid = wrkSht.Cells(iRijnummer, iKolomnrCorpID)
            '''''''''''''''''''

            Dim Position As Long, Length As Long
            Dim n As String
            Position = InStrRev(naam, " ")
            Length = Len(naam)
            n = Right(naam, Length - Position)
        End If

'If n and ldg are numbers this will add them rather than stick them together.
'    naamOpmaken = n + "-" + ldg + "-" + cid

    ''''''''''''''''
    'New code
    naamOpmaken = n & "-" & ldg & "-" & cid
    ''''''''''''''''

End Function

'New function to find last cell containing data on sheet.
Public Function LastCell(wrkSht As Worksheet) As Range

    Dim lLastCol As Long, lLastRow As Long

    On Error Resume Next

    With wrkSht
        lLastCol = .Cells.Find("*", , , , xlByColumns, xlPrevious).Column
        lLastRow = .Cells.Find("*", , , , xlByRows, xlPrevious).row

        If lLastCol = 0 Then lLastCol = 1
        If lLastRow = 0 Then lLastRow = 1

        Set LastCell = wrkSht.Cells(lLastRow, lLastCol)
    End With
    On Error GoTo 0

End Function

Upvotes: 1

DisplayName
DisplayName

Reputation: 13386

you have to activate a worksheet before selecting a cell of

since you're jumping between sheets you have to add

WsStam.Activate

right before

WsStam.Cells(row, iKolomnrCorpID).EntireRow.Select

BTW, you don't seem to need that selection at all so you may want to try and comment that line!

Upvotes: 1

Related Questions