Tested your code and works.
It must be something else.
As a workaround, you can select your grid in form designer, save it as class (grdInvoices) in a class library and, instead your code, write:
IF !USED("invoices")
USE w:\invoices.dbf IN 0 ALIAS invoices
ENDIF
SELECT invoices
local lnGrdTop, lngrdLeft
lnGrdTop = THISFORM.PAGEFRAME1.PAGE3.grid1.top
lnGrdLeft = THISFORM.PAGEFRAME1.PAGE3.grid1.Left
THISFORM.LockScreen = .T.
THISFORM.PAGEFRAME1.PAGE3.RemoveObject('Grid1')
THISFORM.PAGEFRAME1.PAGE3.AddObject('Grid1','grdInvoices')
THISFORM.PAGEFRAME1.PAGE3.grid1.top = lnGrdTop
THISFORM.PAGEFRAME1.PAGE3.grid1.Left = lnGrdLeft
THISFORM.PAGEFRAME1.PAGE3.grid1.visible = .T.
THISFORM.LockScreen = .F.
You need SET CLASSLIB to {classlib} or you can use NewObject method instead of AddObject
>This is the code in the valid event of the button I retrieve the details with.
>
>THISFORM.PAGEFRAME1.PAGE3.grid1.recordsource = ""
>IF !USED("invoices")
> USE w:\invoices.dbf IN 0 ALIAS invoices
>ENDIF
>SELECT invoices
>THISFORM.PAGEFRAME1.PAGE3.grid1.recordsource = "invoices"
>THISFORM.PAGEFRAME1.PAGE3.grid1.recordsourcetype = 1
>THISFORM.PAGEFRAME1.PAGE3.grid1.columncount = 4
>THISFORM.PAGEFRAME1.PAGE3.grid1.column1.header1.caption = "Invoice No."
>THISFORM.PAGEFRAME1.PAGE3.grid1.column2.header1.caption = "Invoice Date"
>THISFORM.PAGEFRAME1.PAGE3.grid1.column3.header1.caption = "Invoice Total"
>
>This is the code in the Text 1 Click Event of the Invoice No Column.
>
>DO FORM invoice LINKED