R
RB Smissaert
That code wasn't tested and indeed it is no good at all, mainly because I
didn't consider the fact
that an array produced by rs.GetArray is transposed.
Shortly after I posted better code (via a phone), but it didn't come
through.
Try this code instead:
Sub test3()
Dim LR As Long
StartSW
LR = GetSheetLastDataRow("C:\ExcelFiles\TestLastRow2003.xls", "Sheet1")
StopSW , "last data row: " & LR & ", done with ADO"
End Sub
Function GetSheetLastDataRow(strWB As String, _
strSheet As String, _
Optional lColumn As Long = -1) As Long
Dim rs As ADODB.Recordset
Dim strConn As String
Dim strSQL As String
Dim arr
Dim LR As Long
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strWB & ";" & _
"Extended Properties=Excel 8.0;"
strSQL = "SELECT * FROM [" & strSheet & "$]"
Set rs = New ADODB.Recordset
rs.Open strSQL, strConn, adOpenStatic, adLockReadOnly, adCmdText
arr = rs.GetRows
GetSheetLastDataRow = GetArrayLastDataRow(arr, lColumn) + 1 'add one as
0-based array
End Function
Function GetArrayLastDataRow(arr As Variant, Optional lColumn As Long = -1)
As Long
'note that the passed array is transposed as it is produced by rs.GetRows
'------------------------------------------------------------------------
Dim r As Long
Dim c As Long
Dim LR As Long
Dim UB As Long
Dim UB2 As Long
Dim LB As Long
Dim LB2 As Long
'note the bounds are reversed due to the supplied array being transposed
'-----------------------------------------------------------------------
UB = UBound(arr, 2)
UB2 = UBound(arr)
LB = LBound(arr, 2)
LB2 = LBound(arr)
GetArrayLastDataRow = LB
'as sheet columns are 1-based, but this array is 0-based
'-------------------------------------------------------
If lColumn > 0 Then
lColumn = lColumn - 1
End If
If lColumn = -1 Then
For c = LB2 To UB2
For r = UB To GetArrayLastDataRow Step -1
If IsNull(arr(c, r)) = False Then
If r > GetArrayLastDataRow Then
GetArrayLastDataRow = r
End If
Exit For
End If
Next r
Next c
Else
For r = UB To GetArrayLastDataRow Step -1
If IsNull(arr(lColumn, r)) = False Then
If r > GetArrayLastDataRow Then
GetArrayLastDataRow = r
End If
Exit For
End If
Next r
End If
End Function
Note here that the final row result is the table row, so the field row is
zero and the first row is row 1.
This means that it is not the same as the sheet row. It works fine with me
and is reasonably quick.
RBS
didn't consider the fact
that an array produced by rs.GetArray is transposed.
Shortly after I posted better code (via a phone), but it didn't come
through.
Try this code instead:
Sub test3()
Dim LR As Long
StartSW
LR = GetSheetLastDataRow("C:\ExcelFiles\TestLastRow2003.xls", "Sheet1")
StopSW , "last data row: " & LR & ", done with ADO"
End Sub
Function GetSheetLastDataRow(strWB As String, _
strSheet As String, _
Optional lColumn As Long = -1) As Long
Dim rs As ADODB.Recordset
Dim strConn As String
Dim strSQL As String
Dim arr
Dim LR As Long
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strWB & ";" & _
"Extended Properties=Excel 8.0;"
strSQL = "SELECT * FROM [" & strSheet & "$]"
Set rs = New ADODB.Recordset
rs.Open strSQL, strConn, adOpenStatic, adLockReadOnly, adCmdText
arr = rs.GetRows
GetSheetLastDataRow = GetArrayLastDataRow(arr, lColumn) + 1 'add one as
0-based array
End Function
Function GetArrayLastDataRow(arr As Variant, Optional lColumn As Long = -1)
As Long
'note that the passed array is transposed as it is produced by rs.GetRows
'------------------------------------------------------------------------
Dim r As Long
Dim c As Long
Dim LR As Long
Dim UB As Long
Dim UB2 As Long
Dim LB As Long
Dim LB2 As Long
'note the bounds are reversed due to the supplied array being transposed
'-----------------------------------------------------------------------
UB = UBound(arr, 2)
UB2 = UBound(arr)
LB = LBound(arr, 2)
LB2 = LBound(arr)
GetArrayLastDataRow = LB
'as sheet columns are 1-based, but this array is 0-based
'-------------------------------------------------------
If lColumn > 0 Then
lColumn = lColumn - 1
End If
If lColumn = -1 Then
For c = LB2 To UB2
For r = UB To GetArrayLastDataRow Step -1
If IsNull(arr(c, r)) = False Then
If r > GetArrayLastDataRow Then
GetArrayLastDataRow = r
End If
Exit For
End If
Next r
Next c
Else
For r = UB To GetArrayLastDataRow Step -1
If IsNull(arr(lColumn, r)) = False Then
If r > GetArrayLastDataRow Then
GetArrayLastDataRow = r
End If
Exit For
End If
Next r
End If
End Function
Note here that the final row result is the table row, so the field row is
zero and the first row is row 1.
This means that it is not the same as the sheet row. It works fine with me
and is reasonably quick.
RBS