Q:

Excel VBA Looping & Closing

Sub CommandButton1_Click()
  Dim wdApp As Word.Application
  Dim wdDoc As Word.Document
  Dim wdRng As Word.Range
  Dim wdPath As String
  Dim i As Integer

  wdPath = "C:\Users\840\Desktop\TP CLients\"
  ThisWorkbook.ActiveSheet.Range("A1:D1").Copy 'Excel sheet of condensed 
  Timesheets
  Set wdApp = New Word.Application
  Set wdDoc = wdApp.Documents.Open(wdPath & "LOA3.docm") ' Create a new document
  With wdDoc
    'Populate the document
     Set wdRng = .Bookmarks("Refnos").Range
     wdRng.PasteAndFormat (wdPasteDefault)
    .Bookmarks.Add "Refnos", wdRng
    'Save the document
    .SaveAs2 Filename:=wdPath & "LOA - " & Range("A1").Text & ".docm", _
    FileFormat:=wdFormatXMLDocument, AddToRecentFiles:=False
  End With
  wdApp.Visible = True
  Set wdDoc = Nothing: Set wdApp = Nothing
End Sub

I have the above code for creating a word document from Excel. It currently saves based on cell value A1. I am wanting to Loop this to then go to the next line i.e. A2:D2 and use A2 as cell name, for the next available line. If nothing is there I want it to stop.
Also when using wdApp.quit this makes my file corrupt. When I try to open the file I get the error message: We cannot open file because we found a problem with its contents. Details: No Error details available. I have tried Application.quit however this tries to also close my excel sheet which I don't want it to do. This is a side topic if you have any input.

A:

Instead of forcing the wdApp object to Quit (which is essentially just closing the process, not the document), close the document itself. You may find this documentation useful: https://msdn.microsoft.com/en-us/VBA/Word-VBA/articles/document-close-method-word.
Next, you can easily loop through cells in a range (though the practice is generally not desirable). For example's sake though:
Sub CommandButton1_Click()
    Dim wdPath As String
    wdPath = "C:\Users\840\Desktop\TP CLients\"

    Dim wdApp As Word.Application
    Set wdApp = New Word.Application
    wdApp.Visible = True

    Dim InputSheet As Worksheet
    Set InputSheet = ThisWorkbook.ActiveSheet

    Dim RowForInput As Long
    RowForInput = 1
    Do Until InputSheet.Range("A" & RowForInput).value = vbNullString
        InputSheet.Range("A" & RowForInput & ":D" & RowForInput).Copy 'Excel sheet of condensed

        Timesheets

        Dim wdDoc As Word.Document
        Set wdDoc = wdApp.Documents.Open(wdPath & "LOA3.docm") ' Create a new document

        With wdDoc
            'Populate the document
            Dim wdRng As Word.Range
            Set wdRng = .bookmarks("Refnos").Range

            wdRng.PasteAndFormat (wdPasteDefault)

            .bookmarks.Add "Refnos", wdRng
            'Save the document
            .SaveAs2 Filename:=wdPath & "LOA - " & Range("A" & RowForInput).Text & ".docm", _
                     FileFormat:=wdFormatXMLDocument, AddToRecentFiles:=False

            .Close True
        End With

        ' You dont need these. Once the procedure finishes these variables will go out of
        ' scope and will be released. Keep in mind, setting them to `Nothing` does not tear them down.
        ' It just releases the pointer to the object itself.

        ' Set wdDoc = Nothing: Set wdApp = Nothing
        RowForInput = RowForInput + 1
    Loop

    wdApp.Quit
End Sub

Note that I made some adjustments to the code overall. It is best practice to declare variables as close to first use as possible, instead of using a Dim block. I also removed the Set wdApp = New Word.Application from the loop. There is absolutely no need to create an application in a loop. I also removed your call to Set wdDoc = Nothing and Set wdApp = Nothing. The common misconception here is that Set Foo = Nothing will take care of the process magically, but really it just removes the pointer to the object. In layman's terms, we no longer have a name for the Object running somewhere in the process. When all the pointers are gone for an object, it is released, or cleaned up. During the release process, the memory allocated for an object (or other variable) is no longer allocated.
The problem is that if you do something like:
Sub Foo()
    Dim App As Excel.Application
    Set App = New Excel.Application
    Set App = Nothing
End Sub

And then check your task manager, you'll see what EXCEL.EXE is still running. We never told it to Quit and so it never did.
Keep this distinction in mind when creating additional Application objects, and remember that for VBA Applications have Quit and Documents or Workbooks etc. have Close. The two are not the same.

