Finding last row data in other worksheet

D

donh

Hi,

I'm very rusty with excel and need your help. I'm using Excel 2003.

I need to insert a worksheet into an existing workbook, which I have
an existing bit of VBA to do, and need this inserted sheet sheet to
have an INDIRECT? function to gather the contents of the last row in a
given column. I have the formula to retrieve a known cell

=INDIRECT("'Purchase Req. form'!$D$3")

but don't have the knowledge to turn that cell refrence into the last
row of a given column.

Thanks for any help

Don
 
D

donh

Hi,

I'm very rusty with excel and need your help.  I'm using Excel 2003.

I need to insert a worksheet into an existing workbook, which I have
an existing bit  of VBA to do, and need this inserted sheet sheet to
have an INDIRECT? function to gather the contents of the last row in a
given column.  I have the formula to retrieve a known cell

=INDIRECT("'Purchase Req. form'!$D$3")

but don't have the knowledge to turn that cell refrence into the last
row of a given column.

Thanks for any help

Don

I've been working my way through my rusty brain and have come up with

=INDIRECT("'Data Sheet'!A"&COUNTA('Data Sheet'!A:A))

which seems to work. Are there any thoughts against this solution?

Many thanks

Don
 
D

Dave Peterson

=indirect() will recalculate each time excel recalculates. It's a volatile
function. Other functions only recalculate when something in one of the
arguments changes.

=sum(a1:A10)
will only recalculate when something changes in A1:A10 (or you do a manual
recalc).

If you have lots of these volatile functions, you may find the time to recalc
goes up.

But since you don't skip any cells in that range (you're trusting =counta()),
you could also use:

=INDEX('Data Sheet'!A:A,COUNTA('Data Sheet'!A:A))
 
D

donh

=indirect() will recalculate each time excel recalculates.  It's a volatile
function.  Other functions only recalculate when something in one of the
arguments changes.

=sum(a1:A10)
will only recalculate when something changes in A1:A10 (or you do a manual
recalc).

If you have lots of these volatile functions, you may find the time to recalc
goes up.

But since you don't skip any cells in that range (you're trusting =counta()),
you could also use:

=INDEX('Data Sheet'!A:A,COUNTA('Data Sheet'!A:A))











--

Dave Peterson- Hide quoted text -

- Show quoted text -


Dave,

Thank you for your reply. The scenario is that my boss is able to do
a printer statistics dump to a spreadsheet that shows who has used it
and how many pages were printed etc. Depending on how many times the
printers have been used a total row will appear in a row at the
bottom.

There are a dozen or so printers to capture data for and rather than
compile all this manually I was trying to use some VBA that I used
years ago that could insert a sheet that used the INDIRECT function to
capture the main totals, with the other section of VBA bringing the
data back out again to a single worksheet. I’ve looked at the code to
see if I could find where I got it from but there isn’t an authors
comment, but anyway it used to work just fine in the role it was used
for previously.

Since I last posted I’ve tried running my VBA and it inserts the page
fine but the formula as is, is referring back to the workbook that it
just came from. I will have a look at your suggestion but would also
appreciate any comments to get my formula working correctly

=INDIRECT("'Sheet1'!F"&COUNTA(Sheet1!F:F))

Many thanks

Don
 
D

Don Guillett

Post YOUR code for comments. It could be something as simple as
currentlastrow=ACTIVESHEET.cells(rows.count,1).end(xlup).row
or
currentlastrow=ACTIVESHEET.cells(rows.count,1).end(xlup).row
or one I use often
lr = Cells.Find(What:="*", SearchDirection:=xlPrevious).Row

--
Don Guillett
Microsoft MVP Excel
SalesAid Software
(e-mail address removed)
=indirect() will recalculate each time excel recalculates. �It's a
volatile
function. �Other functions only recalculate when something in one of the
arguments changes.

=sum(a1:A10)
will only recalculate when something changes in A1:A10 (or you do a manual
recalc).

If you have lots of these volatile functions, you may find the time to
recalc
goes up.

But since you don't skip any cells in that range (you're trusting
=counta()),
you could also use:

=INDEX('Data Sheet'!A:A,COUNTA('Data Sheet'!A:A))











--

Dave Peterson- Hide quoted text -

- Show quoted text -


Dave,

Thank you for your reply. The scenario is that my boss is able to do
a printer statistics dump to a spreadsheet that shows who has used it
and how many pages were printed etc. Depending on how many times the
printers have been used a total row will appear in a row at the
bottom.

There are a dozen or so printers to capture data for and rather than
compile all this manually I was trying to use some VBA that I used
years ago that could insert a sheet that used the INDIRECT function to
capture the main totals, with the other section of VBA bringing the
data back out again to a single worksheet. I�ve looked at the code to
see if I could find where I got it from but there isn�t an authors
comment, but anyway it used to work just fine in the role it was used
for previously.

Since I last posted I�ve tried running my VBA and it inserts the page
fine but the formula as is, is referring back to the workbook that it
just came from. I will have a look at your suggestion but would also
appreciate any comments to get my formula working correctly

=INDIRECT("'Sheet1'!F"&COUNTA(Sheet1!F:F))

Many thanks

Don
 
D

Dave Peterson

I'd still use the =index() version of the formula.

But if you're copying a worksheet from a workbook that has this formula, then
the second part of the formula:

This portion:
Sheet1!F:F
in this expression:
=INDIRECT("'Sheet1'!F"&COUNTA(Sheet1!F:F))

will point back to the original workbook.
'[someworkbook.xls]sheet1'!f:F

I'd either make a change to the procedure that copied the sheet (convert the
formulas to plain old strings) by:

Edit|Replace
what: =
with: $$$$$=
replace all
(against all the cells on all the sheets that are copied)

Then change them back in the original and new sheets after the copy.

Or build the formula in code and plop it into the required cell(s).
or drop the formula completely and do everything in code.
 
D

donh

Thank you both for your comments. I will post the VBA that I use
(it's not mine, its something I was either given or pointed to years
ago) at the end, but as originally posted am rusty with excel and
wanted to try keep things as simple as possible.

I used the INDIRECT function to avoid the reference back to the
originating sheet and this did work well when I knew the target cell
address.

=INDIRECT("'Purchase Req. form'!$D$4")

In my current scenario as these reports generate an unknown number of
rows I do not have a known cell row address hence the need for trying
to find last row containing data.

Once again I have a formula that does that but when used referes back
to the originating sheet not the one I've inserted it into

=INDIRECT("'Sheet1'!F"&COUNTA(Sheet1!F:F))

turns into

=INDIRECT("'Sheet1'!F"&COUNTA([PrinterDataCapture.xls]Sheet1!F:F))

For my level of understanding I just need to modify the COUNTA section
to be INDIRECT to find the last row cell in my target workbook.

The VBA used to copy sheet with INDIRECT formulas into folder
containing excel workbooks is:

Sub Copy_Sheet_1()
Dim basebook As Workbook
Dim mybook As Workbook
Dim sourceRange As Range
Dim destrange As Range
Dim FNames As String
Dim MyPath As String
Dim SaveDriveDir As String

SaveDriveDir = CurDir

MyPath = "G:\New"
'Add a slash at the end if the user forget
If Right(MyPath, 1) <> "\" Then
MyPath = MyPath & "\"
End If

ChDrive MyPath
ChDir MyPath
FNames = Dir("*.xls")
If Len(FNames) = 0 Then
MsgBox "No files in the Directory"
ChDrive SaveDriveDir
ChDir SaveDriveDir
Exit Sub
End If

On Error GoTo CleanUp
Application.ScreenUpdating = False

Set basebook = ThisWorkbook
Do While FNames <> ""
Set mybook = Workbooks.Open(FNames)

basebook.Worksheets("Sheet2").Copy after:= _

mybook.Sheets(mybook.Sheets.Count)
On Error Resume Next
ActiveSheet.Name = basebook.Name
On Error GoTo 0

' You can use this if you want to change the formulas to
values
' With ActiveSheet.UsedRange
' .Value = .Value
' End With

mybook.Close True
FNames = Dir()
Loop

CleanUp:
ChDrive SaveDriveDir
ChDir SaveDriveDir
Application.ScreenUpdating = True
End Sub



VBA to capture data from worksheet just inserted and pulls into single
new worksheet is:

Sub GetData_Example7()
'Copy cells from folder and subfolder(s)
Dim SubFolders As Boolean
Dim Fso_Obj As Object, RootFolder As Object
Dim SubFolderInRoot As Object, file As Object
Dim RootPath As String, FileExt As String
Dim MyFiles() As String, Fnum As Long
Dim sh As Worksheet, destrange As Range
Dim rnum As Long

'Loop through all files in the Root folder
'RootPath = "C:\Data"
RootPath = "G:\Cad\WEB FILES\Test files\mv\"
'Loop through the subfolders True or False
SubFolders = True

'Loop through files with this extension
FileExt = ".xls"

'Add a slash at the end if the user forget it
If Right(RootPath, 1) <> "\" Then
RootPath = RootPath & "\"
End If

Set Fso_Obj = CreateObject("Scripting.FileSystemObject")
If Not Fso_Obj.FolderExists(RootPath) Then
MsgBox RootPath & " Not exist"
Exit Sub
End If

Set RootFolder = Fso_Obj.GetFolder(RootPath)

'Fill the array(myFiles)with the list of Excel files in the
folder(s)
Fnum = 0

'Loop through the files in the RootFolder
For Each file In RootFolder.Files
If LCase(Right(file.Name, 4)) = FileExt Then
Fnum = Fnum + 1
ReDim Preserve MyFiles(1 To Fnum)
MyFiles(Fnum) = RootPath & file.Name
End If
Next file

'Loop through the files in the Sub Folders if SubFolders = True
If SubFolders Then
For Each SubFolderInRoot In RootFolder.SubFolders
For Each file In SubFolderInRoot.Files
If LCase(Right(file.Name, 4)) = FileExt Then
Fnum = Fnum + 1
ReDim Preserve MyFiles(1 To Fnum)
MyFiles(Fnum) = SubFolderInRoot & "\" & file.Name
End If
Next file
Next SubFolderInRoot
End If

' Now we can loop through the files in the array MyFiles to get
the cell values

'******************************************************************

'Add worksheet to the Activeworkbook and use the Date/Time as name
Set sh = ActiveWorkbook.Worksheets.Add
sh.Name = Format(Now, "dd-mm-yy h-mm-ss")

If Fnum > 0 Then
For Fnum = LBound(MyFiles) To UBound(MyFiles)

'Find the last row with data
rnum = LastRow(sh)

'create the destination cell address
Set destrange = sh.Cells(rnum + 1, "A")

' Copy the workbook name in Column E
sh.Cells(rnum + 1, "E").Value = MyFiles(Fnum)

'Get the cell values and copy it in the destrange
'Change the Sheet name and range as you like
GetData MyFiles(Fnum), "Link", "A3:DC3", destrange, False,
False

Next
End If
End Sub



Hope that tells the whole picture and look forward to any response.

Thanks as always for your help

Don
 
D

Dave Peterson

I don't understand what the question is and how it fits into the code you
posted.
Thank you both for your comments. I will post the VBA that I use
(it's not mine, its something I was either given or pointed to years
ago) at the end, but as originally posted am rusty with excel and
wanted to try keep things as simple as possible.

I used the INDIRECT function to avoid the reference back to the
originating sheet and this did work well when I knew the target cell
address.

=INDIRECT("'Purchase Req. form'!$D$4")

In my current scenario as these reports generate an unknown number of
rows I do not have a known cell row address hence the need for trying
to find last row containing data.

Once again I have a formula that does that but when used referes back
to the originating sheet not the one I've inserted it into

=INDIRECT("'Sheet1'!F"&COUNTA(Sheet1!F:F))

turns into

=INDIRECT("'Sheet1'!F"&COUNTA([PrinterDataCapture.xls]Sheet1!F:F))

For my level of understanding I just need to modify the COUNTA section
to be INDIRECT to find the last row cell in my target workbook.

The VBA used to copy sheet with INDIRECT formulas into folder
containing excel workbooks is:

Sub Copy_Sheet_1()
Dim basebook As Workbook
Dim mybook As Workbook
Dim sourceRange As Range
Dim destrange As Range
Dim FNames As String
Dim MyPath As String
Dim SaveDriveDir As String

SaveDriveDir = CurDir

MyPath = "G:\New"
'Add a slash at the end if the user forget
If Right(MyPath, 1) <> "\" Then
MyPath = MyPath & "\"
End If

ChDrive MyPath
ChDir MyPath
FNames = Dir("*.xls")
If Len(FNames) = 0 Then
MsgBox "No files in the Directory"
ChDrive SaveDriveDir
ChDir SaveDriveDir
Exit Sub
End If

On Error GoTo CleanUp
Application.ScreenUpdating = False

Set basebook = ThisWorkbook
Do While FNames <> ""
Set mybook = Workbooks.Open(FNames)

basebook.Worksheets("Sheet2").Copy after:= _

mybook.Sheets(mybook.Sheets.Count)
On Error Resume Next
ActiveSheet.Name = basebook.Name
On Error GoTo 0

' You can use this if you want to change the formulas to
values
' With ActiveSheet.UsedRange
' .Value = .Value
' End With

mybook.Close True
FNames = Dir()
Loop

CleanUp:
ChDrive SaveDriveDir
ChDir SaveDriveDir
Application.ScreenUpdating = True
End Sub

VBA to capture data from worksheet just inserted and pulls into single
new worksheet is:

Sub GetData_Example7()
'Copy cells from folder and subfolder(s)
Dim SubFolders As Boolean
Dim Fso_Obj As Object, RootFolder As Object
Dim SubFolderInRoot As Object, file As Object
Dim RootPath As String, FileExt As String
Dim MyFiles() As String, Fnum As Long
Dim sh As Worksheet, destrange As Range
Dim rnum As Long

'Loop through all files in the Root folder
'RootPath = "C:\Data"
RootPath = "G:\Cad\WEB FILES\Test files\mv\"
'Loop through the subfolders True or False
SubFolders = True

'Loop through files with this extension
FileExt = ".xls"

'Add a slash at the end if the user forget it
If Right(RootPath, 1) <> "\" Then
RootPath = RootPath & "\"
End If

Set Fso_Obj = CreateObject("Scripting.FileSystemObject")
If Not Fso_Obj.FolderExists(RootPath) Then
MsgBox RootPath & " Not exist"
Exit Sub
End If

Set RootFolder = Fso_Obj.GetFolder(RootPath)

'Fill the array(myFiles)with the list of Excel files in the
folder(s)
Fnum = 0

'Loop through the files in the RootFolder
For Each file In RootFolder.Files
If LCase(Right(file.Name, 4)) = FileExt Then
Fnum = Fnum + 1
ReDim Preserve MyFiles(1 To Fnum)
MyFiles(Fnum) = RootPath & file.Name
End If
Next file

'Loop through the files in the Sub Folders if SubFolders = True
If SubFolders Then
For Each SubFolderInRoot In RootFolder.SubFolders
For Each file In SubFolderInRoot.Files
If LCase(Right(file.Name, 4)) = FileExt Then
Fnum = Fnum + 1
ReDim Preserve MyFiles(1 To Fnum)
MyFiles(Fnum) = SubFolderInRoot & "\" & file.Name
End If
Next file
Next SubFolderInRoot
End If

' Now we can loop through the files in the array MyFiles to get
the cell values

'******************************************************************

'Add worksheet to the Activeworkbook and use the Date/Time as name
Set sh = ActiveWorkbook.Worksheets.Add
sh.Name = Format(Now, "dd-mm-yy h-mm-ss")

If Fnum > 0 Then
For Fnum = LBound(MyFiles) To UBound(MyFiles)

'Find the last row with data
rnum = LastRow(sh)

'create the destination cell address
Set destrange = sh.Cells(rnum + 1, "A")

' Copy the workbook name in Column E
sh.Cells(rnum + 1, "E").Value = MyFiles(Fnum)

'Get the cell values and copy it in the destrange
'Change the Sheet name and range as you like
GetData MyFiles(Fnum), "Link", "A3:DC3", destrange, False,
False

Next
End If
End Sub

Hope that tells the whole picture and look forward to any response.

Thanks as always for your help

Don
 
D

donh

I don't understand what the question is and how it fits into the code you
posted.




Thank you both for your comments.  I will post the VBA that I use
(it's not mine, its something I was either given or pointed to years
ago) at the end, but as originally posted am rusty with excel and
wanted to try keep things as simple as possible.
I used the INDIRECT function to avoid the reference back to the
originating sheet and this did work well when I knew the target cell
address.
=INDIRECT("'Purchase Req. form'!$D$4")
In my current scenario as these reports generate an unknown number of
rows I do not have a known cell row address hence the need for trying
to find last row containing data.
Once again I have a formula that does that but when used referes back
to the originating sheet not the one I've inserted it into
=INDIRECT("'Sheet1'!F"&COUNTA(Sheet1!F:F))

turns into
=INDIRECT("'Sheet1'!F"&COUNTA([PrinterDataCapture.xls]Sheet1!F:F))

For my level of understanding I just need to modify the COUNTA section
to be INDIRECT to find the last row cell in my target workbook.
The VBA used to copy sheet with INDIRECT formulas into folder
containing excel workbooks is:
Sub Copy_Sheet_1()
    Dim basebook As Workbook
    Dim mybook As Workbook
    Dim sourceRange As Range
    Dim destrange As Range
    Dim FNames As String
    Dim MyPath As String
    Dim SaveDriveDir As String
    SaveDriveDir = CurDir
    MyPath = "G:\New"
    'Add a slash at the end if the user forget
    If Right(MyPath, 1) <> "\" Then
        MyPath = MyPath & "\"
    End If
    ChDrive MyPath
    ChDir MyPath
    FNames = Dir("*.xls")
    If Len(FNames) = 0 Then
        MsgBox "No files in the Directory"
        ChDrive SaveDriveDir
        ChDir SaveDriveDir
        Exit Sub
    End If
    On Error GoTo CleanUp
    Application.ScreenUpdating = False
    Set basebook = ThisWorkbook
    Do While FNames <> ""
        Set mybook = Workbooks.Open(FNames)
        basebook.Worksheets("Sheet2").Copy after:= _
mybook.Sheets(mybook.Sheets.Count)
        On Error Resume Next
        ActiveSheet.Name = basebook.Name
        On Error GoTo 0
        ' You can use this if you want to change the formulas to
values
        '        With ActiveSheet.UsedRange
        '            .Value = .Value
        '        End With
        mybook.Close True
        FNames = Dir()
    Loop
CleanUp:
    ChDrive SaveDriveDir
    ChDir SaveDriveDir
    Application.ScreenUpdating = True
End Sub
VBA to capture data from worksheet just inserted and pulls into single
new worksheet is:
Sub GetData_Example7()
'Copy cells from folder and subfolder(s)
    Dim SubFolders As Boolean
    Dim Fso_Obj As Object, RootFolder As Object
    Dim SubFolderInRoot As Object, file As Object
    Dim RootPath As String, FileExt As String
    Dim MyFiles() As String, Fnum As Long
    Dim sh As Worksheet, destrange As Range
    Dim rnum As Long
    'Loop through all files in the Root folder
    'RootPath = "C:\Data"
    RootPath = "G:\Cad\WEB FILES\Test files\mv\"
    'Loop through the subfolders True or False
    SubFolders = True
    'Loop through files with this extension
    FileExt = ".xls"
    'Add a slash at the end if the user forget it
    If Right(RootPath, 1) <> "\" Then
        RootPath = RootPath & "\"
    End If
    Set Fso_Obj = CreateObject("Scripting.FileSystemObject")
    If Not Fso_Obj.FolderExists(RootPath) Then
        MsgBox RootPath & "  Not exist"
        Exit Sub
    End If
    Set RootFolder = Fso_Obj.GetFolder(RootPath)
    'Fill the array(myFiles)with the list of Excel files in the
folder(s)
    Fnum = 0
    'Loop through the files in the RootFolder
    For Each file In RootFolder.Files
        If LCase(Right(file.Name, 4)) = FileExt Then
            Fnum = Fnum + 1
            ReDim Preserve MyFiles(1 To Fnum)
            MyFiles(Fnum) = RootPath & file.Name
        End If
    Next file
    'Loop through the files in the Sub Folders if SubFolders = True
    If SubFolders Then
        For Each SubFolderInRoot In RootFolder.SubFolders
            For Each file In SubFolderInRoot.Files
                If LCase(Right(file.Name, 4)) = FileExt Then
                    Fnum = Fnum + 1
                    ReDim Preserve MyFiles(1 To Fnum)
                    MyFiles(Fnum) = SubFolderInRoot & "\" & file.Name
                End If
            Next file
        Next SubFolderInRoot
    End If
    ' Now we can loop through the files in the array MyFiles to get
the cell values

    'Add worksheet to the Activeworkbook and use the Date/Time as name
    Set sh = ActiveWorkbook.Worksheets.Add
    sh.Name = Format(Now, "dd-mm-yy h-mm-ss")
    If Fnum > 0 Then
        For Fnum = LBound(MyFiles) To UBound(MyFiles)
            'Find the last row with data
            rnum = LastRow(sh)
            'create the destination cell address
            Set destrange = sh.Cells(rnum + 1, "A")
            ' Copy the workbook name in Column E
            sh.Cells(rnum + 1, "E").Value = MyFiles(Fnum)
            'Get the cell values and copy it in the destrange
            'Change the Sheet name and range as you like
            GetData MyFiles(Fnum), "Link", "A3:DC3", destrange, False,
False
        Next
    End If
End Sub
Hope that tells the whole picture and look forward to any response.
Thanks as always for your help

--

Dave Peterson- Hide quoted text -

- Show quoted text -

Hi Dave,

The question has escallated further than I wanted to go. I need a
formula that can be used in a worksheet that can then be copied into
another workbook. I want this formula to refer to the workbook it is
in, not where it has come from, hence the INDIRECT() the example
formula =INDIRECT("'Purchase Req. form'!$D$4") works fine when I know
what cell I'm getting the data from (the worksheet Purchase Req.
already being in the target workbook). My poroblem is that as the
target workbook is a data dump I do not know what the last row is, so
am trying to find out the syntax that ties the INDIRECT function of a
known cell address with the COUNTA() of an unknown row number to get a
formula that can be inserted from within a worksheet of another
workbook into a workbook with a known worksheet name, with a known
column but with an unknown last row.

I hope that makes sense.

Thanks for bearing with this.

Don
 
D

donh

I don't understand what the question is and how it fits into the code you
posted.
donh wrote:
Thank you both for your comments.  I will post the VBA that I use
(it's not mine, its something I was either given or pointed to years
ago) at the end, but as originally posted am rusty with excel and
wanted to try keep things as simple as possible.
I used the INDIRECT function to avoid the reference back to the
originating sheet and this did work well when I knew the target cell
address.
=INDIRECT("'Purchase Req. form'!$D$4")
In my current scenario as these reports generate an unknown number of
rows I do not have a known cell row address hence the need for trying
to find last row containing data.
Once again I have a formula that does that but when used referes back
to the originating sheet not the one I've inserted it into
=INDIRECT("'Sheet1'!F"&COUNTA(Sheet1!F:F))
turns into
=INDIRECT("'Sheet1'!F"&COUNTA([PrinterDataCapture.xls]Sheet1!F:F))
For my level of understanding I just need to modify the COUNTA section
to be INDIRECT to find the last row cell in my target workbook.
The VBA used to copy sheet with INDIRECT formulas into folder
containing excel workbooks is:
Sub Copy_Sheet_1()
    Dim basebook As Workbook
    Dim mybook As Workbook
    Dim sourceRange As Range
    Dim destrange As Range
    Dim FNames As String
    Dim MyPath As String
    Dim SaveDriveDir As String
    SaveDriveDir = CurDir
    MyPath = "G:\New"
    'Add a slash at the end if the user forget
    If Right(MyPath, 1) <> "\" Then
        MyPath = MyPath & "\"
    End If
    ChDrive MyPath
    ChDir MyPath
    FNames = Dir("*.xls")
    If Len(FNames) = 0 Then
        MsgBox "No files in the Directory"
        ChDrive SaveDriveDir
        ChDir SaveDriveDir
        Exit Sub
    End If
    On Error GoTo CleanUp
    Application.ScreenUpdating = False
    Set basebook = ThisWorkbook
    Do While FNames <> ""
        Set mybook = Workbooks.Open(FNames)
        basebook.Worksheets("Sheet2").Copy after:= _
mybook.Sheets(mybook.Sheets.Count)
        On Error Resume Next
        ActiveSheet.Name = basebook.Name
        On Error GoTo 0
        ' You can use this if you want to change the formulasto
values
        '        With ActiveSheet.UsedRange
        '            .Value = .Value
        '        End With
        mybook.Close True
        FNames = Dir()
    Loop
CleanUp:
    ChDrive SaveDriveDir
    ChDir SaveDriveDir
    Application.ScreenUpdating = True
End Sub
VBA to capture data from worksheet just inserted and pulls into single
new worksheet is:
Sub GetData_Example7()
'Copy cells from folder and subfolder(s)
    Dim SubFolders As Boolean
    Dim Fso_Obj As Object, RootFolder As Object
    Dim SubFolderInRoot As Object, file As Object
    Dim RootPath As String, FileExt As String
    Dim MyFiles() As String, Fnum As Long
    Dim sh As Worksheet, destrange As Range
    Dim rnum As Long
    'Loop through all files in the Root folder
    'RootPath = "C:\Data"
    RootPath = "G:\Cad\WEB FILES\Test files\mv\"
    'Loop through the subfolders True or False
    SubFolders = True
    'Loop through files with this extension
    FileExt = ".xls"
    'Add a slash at the end if the user forget it
    If Right(RootPath, 1) <> "\" Then
        RootPath = RootPath & "\"
    End If
    Set Fso_Obj = CreateObject("Scripting.FileSystemObject")
    If Not Fso_Obj.FolderExists(RootPath) Then
        MsgBox RootPath & "  Not exist"
        Exit Sub
    End If
    Set RootFolder = Fso_Obj.GetFolder(RootPath)
    'Fill the array(myFiles)with the list of Excel files in the
folder(s)
    Fnum = 0
    'Loop through the files in the RootFolder
    For Each file In RootFolder.Files
        If LCase(Right(file.Name, 4)) = FileExt Then
            Fnum = Fnum + 1
            ReDim Preserve MyFiles(1 To Fnum)
            MyFiles(Fnum) = RootPath & file.Name
        End If
    Next file
    'Loop through the files in the Sub Folders if SubFolders = True
    If SubFolders Then
        For Each SubFolderInRoot In RootFolder.SubFolders
            For Each file In SubFolderInRoot.Files
                If LCase(Right(file.Name, 4)) = FileExt Then
                    Fnum = Fnum + 1
                    ReDim Preserve MyFiles(1 To Fnum)
                    MyFiles(Fnum) = SubFolderInRoot & "\" & file.Name
                End If
            Next file
        Next SubFolderInRoot
    End If
    ' Now we can loop through the files in the array MyFiles to get
the cell values
'******************************************************************
    'Add worksheet to the Activeworkbook and use the Date/Time asname
    Set sh = ActiveWorkbook.Worksheets.Add
    sh.Name = Format(Now, "dd-mm-yy h-mm-ss")
    If Fnum > 0 Then
        For Fnum = LBound(MyFiles) To UBound(MyFiles)
            'Find the last row with data
            rnum = LastRow(sh)
            'create the destination cell address
            Set destrange = sh.Cells(rnum + 1, "A")
            ' Copy the workbook name in Column E
            sh.Cells(rnum + 1, "E").Value = MyFiles(Fnum)
            'Get the cell values and copy it in the destrange
            'Change the Sheet name and range as you like
            GetData MyFiles(Fnum), "Link", "A3:DC3", destrange, False,
False
        Next
    End If
End Sub
Hope that tells the whole picture and look forward to any response.
Thanks as always for your help
Don

Dave Peterson- Hide quoted text -
- Show quoted text -

Hi Dave,

The question has escallated further than I wanted to go.  I need a
formula that can be used in a worksheet that can then be copied into
another workbook.  I want this formula to refer to the workbook it is
in, not where it has come from, hence the INDIRECT()  the example
formula =INDIRECT("'Purchase Req. form'!$D$4") works fine when I know
what cell I'm getting the data from (the worksheet Purchase Req.
already being in the target workbook).  My poroblem is that as the
target workbook is a data dump I do not know what the last row is, so
am trying to find out the syntax that ties the INDIRECT function of a
known cell address with the COUNTA() of an unknown row number to get a
formula that can be inserted from within a worksheet of another
workbook into a workbook with a known worksheet name, with a known
column but with an unknown last row.

I hope that makes sense.

Thanks for bearing with this.

Don- Hide quoted text -

- Show quoted text -

I've played further and the answer appears to be


=INDIRECT("'Sheet1'!D"&COUNTA(INDIRECT("'Sheet1'!D:D")))

Thank you for your help

Don
 
D

Dave Peterson

I don't understand how this fits in with the code.

If you only need it for your code, then this line:
rnum = LastRow(sh)
will find that last row.

If you need it for a formula in a cell in a worksheet, then =indirect() will
only work if the sending workbook is open.
 
D

donh

donh wrote:

I don't understand how this fits in with the code.

If you only need it for your code, then this line:
rnum = LastRow(sh)
will find that last row.

If you need it for a formula in a cell in a worksheet, then =indirect()will
only work if the sending workbook is open.












--

Dave Peterson- Hide quoted text -

- Show quoted text -

Hi Dave,

Sorry if it seems I made this more difficult than needs be but as I
said I'm very rusty with Excel and always had to ask for VBA advice
when I was using this for work full time, I never had the chance to
learn VBA in depth and my perhaps long routed INDIRECT function
solution is just a sign of lack of knowledge.

Anyway I have now made a few test runs and am able to insert my
capture sheet and gather the printer data I require at the touch of a
macro button, so my boss is happy.

Many thanks

Don
 
D

Dave Peterson

Glad you got it working.
Hi Dave,

Sorry if it seems I made this more difficult than needs be but as I
said I'm very rusty with Excel and always had to ask for VBA advice
when I was using this for work full time, I never had the chance to
learn VBA in depth and my perhaps long routed INDIRECT function
solution is just a sign of lack of knowledge.

Anyway I have now made a few test runs and am able to insert my
capture sheet and gather the printer data I require at the touch of a
macro button, so my boss is happy.

Many thanks

Don
 
D

donh

Glad you got it working.











--

Dave Peterson- Hide quoted text -

- Show quoted text -

Dave,

I don't know if you want to give this any more time but if I hadn't
had a half solution in mind and came to the group and asked:

Hi ,

I've got a folder that contains 12 workbooks (containing a single
worksheet of interest) These workbooks are the result of a monthly
data dump to monitor printer use. Each of the workbooks has a totals
row at the bottom of the worksheet (but dont know which row this might
be) and I need to be able to bring the totals for just three of the
columns in each workbook together, so I can do a comparison chart
between the printers we use. Can you give me any suggestions?


What might you have suggest as an alternative method?

Many thanks as always

Don
 
D

Dave Peterson

I'd create a macro workbook that retrieve that last row of data from each of the
12 workbooks.

If the folder contains other files as well as these 12, I'd create a list of the
names of the 12 workbooks in one of the sheets of that macro workbook. (If
there are no other files in the folder, you could just loop through all of
them.)

Then I'd have the macro workbook create a new sheet that would hold the last
line of each of these 12 workbooks interested sheets.

I'd put the name of the workbook/worksheet in column A and copy the row (just
the interested columns) into column B of this report worksheet.

Lightly tested:

Option Explicit
Sub testme()

Dim RptWks As Worksheet
Dim SummName As String
Dim TempWkbk As Workbook
Dim TempWks As Worksheet
Dim myCell As Range
Dim myRng As Range
Dim ListWks As Worksheet
Dim myPath As String
Dim LastRow As Long
Dim LastCol As Long
Dim RngToCopy As Range
Dim DestCell As Range

SummName = "Sheet132" '<--what's the common sheet name?

myPath = "C:\my documents\excel\" '<-- change to the correct path
If Right(myPath, 1) <> "\" Then
myPath = myPath & "\"
End If

Set ListWks = ThisWorkbook.Worksheets("List")

With ListWks
'headers in Row 1 of the list worksheet
Set myRng = .Range("A2", .Cells(.Rows.Count, "A").End(xlUp))
myRng.Offset(0, 1).ClearContents 'for results indicator
End With

Set RptWks = Worksheets.Add
With RptWks
.Name = Format(Now, "yyyymmdd_hhmmss")
Set DestCell = .Range("A2")
.Range("a1").Value = "Source"
'more headers go here
End With

For Each myCell In myRng.Cells
Set TempWkbk = Nothing
On Error Resume Next
Set TempWkbk = Workbooks.Open(Filename:=myPath & myCell.Value, _
ReadOnly:=True)
On Error GoTo 0

If TempWkbk Is Nothing Then
myCell.Offset(0, 1).Value = "Couldn't be opened!"
Else
Set TempWks = Nothing
On Error Resume Next
Set TempWks = TempWkbk.Worksheets(SummName)
On Error GoTo 0

If TempWks Is Nothing Then
myCell.Offset(0, 1).Value = "No sheet found!"
Else
With TempWks
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
LastCol = .Cells(LastRow, _
.Columns.Count).End(xlToLeft).Column
Set RngToCopy = .Cells(LastRow, "A").Resize(1, LastCol)

DestCell.Value = TempWkbk.Name & "--" & TempWks.Name
RngToCopy.Copy
DestCell.Offset(0, 1).PasteSpecial Paste:=xlPasteValues
myCell.Offset(0, 1).Value = "Ok"
End With
End If
TempWkbk.Close savechanges:=False
End If
Next myCell

End Sub
 
D

donh

I'd create a macro workbook that retrieve that last row of data from eachof the
12 workbooks.

If the folder contains other files as well as these 12, I'd create a listof the
names of the 12 workbooks in one of the sheets of that macro workbook.  (If
there are no other files in the folder, you could just loop through all of
them.)

Then I'd have the macro workbook create a new sheet that would hold the last
line of each of these 12 workbooks interested sheets.  

I'd put the name of the workbook/worksheet in column A and copy the row (just
the interested columns) into column B of this report worksheet.

Lightly tested:

Option Explicit
Sub testme()

    Dim RptWks As Worksheet
    Dim SummName As String
    Dim TempWkbk As Workbook
    Dim TempWks As Worksheet
    Dim myCell As Range
    Dim myRng As Range
    Dim ListWks As Worksheet
    Dim myPath As String
    Dim LastRow As Long
    Dim LastCol As Long
    Dim RngToCopy As Range
    Dim DestCell As Range

    SummName = "Sheet132" '<--what's the common sheet name?

    myPath = "C:\my documents\excel\"  '<-- change to the correctpath
    If Right(myPath, 1) <> "\" Then
        myPath = myPath & "\"
    End If

    Set ListWks = ThisWorkbook.Worksheets("List")

    With ListWks
        'headers in Row 1 of the list worksheet
        Set myRng = .Range("A2", .Cells(.Rows.Count, "A").End(xlUp))
        myRng.Offset(0, 1).ClearContents 'for results indicator
    End With

    Set RptWks = Worksheets.Add
    With RptWks
        .Name = Format(Now, "yyyymmdd_hhmmss")
        Set DestCell = .Range("A2")
        .Range("a1").Value = "Source"
        'more headers go here
    End With

    For Each myCell In myRng.Cells
        Set TempWkbk = Nothing
        On Error Resume Next
        Set TempWkbk = Workbooks.Open(Filename:=myPath & myCell.Value, _
                                          ReadOnly:=True)
        On Error GoTo 0

        If TempWkbk Is Nothing Then
            myCell.Offset(0, 1).Value = "Couldn't be opened!"
        Else
            Set TempWks = Nothing
            On Error Resume Next
            Set TempWks = TempWkbk.Worksheets(SummName)
            On Error GoTo 0

            If TempWks Is Nothing Then
                myCell.Offset(0, 1).Value = "No sheet found!"
            Else
                With TempWks
                    LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
                    LastCol = .Cells(LastRow, _
                                  .Columns.Count).End(xlToLeft).Column
                    Set RngToCopy = .Cells(LastRow,"A").Resize(1, LastCol)

                    DestCell.Value = TempWkbk.Name & "--" & TempWks.Name
                    RngToCopy.Copy
                    DestCell.Offset(0, 1).PasteSpecial Paste:=xlPasteValues
                    myCell.Offset(0, 1).Value = "Ok"
                End With
            End If
            TempWkbk.Close savechanges:=False
        End If
    Next myCell

End Sub





donhwrote:







--

Dave Peterson- Hide quoted text -

- Show quoted text -

Dave,

Thank you for taking the time to reply. I got side tracked at work
and haven't had the time to reply. I have quickly tried your code but
without success. I think because I didn't set up a list of sheets.
But will have a greater llok next week. Just wanted to say thank you.

Best wishes

Don
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top