I'm having a run-time error 91 and I have no idea why. I used this code for a different workbook and it works perfectly, the information in the columns are different that I'm extracting but I changed all the columns and ranges to the correct one, but now I'm getting this error here and the only difference is the Range, please help!
Range(Cells(20, 1), Cells(LastRow, LastCol)).Select
Selection.AutoFilter
Range("C2").Select
That is the beginning but here is where the error occurs:
ActiveWorkbook.Worksheets(msheet).AutoFilter.Sort.SortFields. _
Add Key:=Range("A20:A" & LastRow), SortOn:=xlSortOnValues, Order:=xlAscending, _
DataOption:=xlSortNormal
Please help, I don't know what I'm missing. Thanks!
Here is the beginning of the code:
Sub getdata()
Dim mastername As String
Dim count As Long
Dim match As Long
Dim repeat As Long
Dim path As String
Dim status As String
Dim name As String
Dim mpath As String
Dim cpath As String
Dim LastRow As Long
Dim LastCol As Integer
Dim mbank As String
Dim mname As String
mpath = Sheets("Master log").Cells(14, "W").Value
mname = Sheets("Master log").Cells(15, "W").Value
msheet = Sheets("Master log").Cells(16, "W").Value
Sheets("MGPR1").Range("A1:AA50000").ClearContents
name = Application.ActiveWorkbook.name
cpath = Application.ActiveWorkbook.path & "\"
Windows(name).Activate
'--open Management report workbook if not already open
If CheckFileIsOpen(mname) = False Then
Workbooks.Open mpath & mname
End If
'-------------------------------------------
Windows(mname).Activate
Sheets(msheet).Select
'select full data
With ActiveSheet
LastRow = .Cells(.Rows.count, "A").End(xlUp).Row
End With
With ActiveSheet
' LastCol = .Cells(1, .Columns.count).End(xlToLeft).Column
LastCol = 20
End With
you have to reference the sheet of the range("A20.....") or else its in activesheet.
Something like sh.range("...") , or use a with section like this example:
with ActiveWorkbook.Worksheets(msheet)
.AutoFilter.Sort.SortFields. _
Add Key:= .Range("A20:A" & LastRow), SortOn:=xlSortOnValues, Order:=xlAscending, _
DataOption:=xlSortNormal
end with
also to help referencing, and stop using activate/select :
Dim Wb as Workbook
Dim Sh as Worksheet
'other code, i just write the needed code now
set wb = Workbooks.Open mpath & mname
set Sh = wb.Sheets(msheet)
with Sh
LastRow = .Cells(.Rows.count, "A").End(xlUp).Row
'lots of stuff to do (....) please wait , computing .... error / no really i try to be serious here!
end with
The meaning of the error is:
91 - Object variable not set
It is obtuse the chain of objects involved. This is a Recorded Macro that does the type of thing you are trying to do. If in doubt unwind a complex statement into simplier ones.
Also always do a Msgbox Vartype(whatever):Msgbox IsEmpty(whatever):msgbox IsNull(whatever). This allows you to check assumptions on what something is.
Range("A1:G19").Select
Selection.AutoFilter
Selection.AutoFilter Field:=3, Criteria1:="<>sub", Operator:=xlAnd
Selection.Sort Key1:=Range("C1"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
Range("H34").Select
Related
I’ve been told that the use of .Select and .Workbooks.Activate is not really a good way to write Vba. The code below tends to work perfectly and there doesn’t seem to be any real issues. The Activeworkbook is not a problem because of Workbooks("FUA.XLSM").Activate. My question is then, what would a good alternative/approach?
I’m sorry if this is a waste of time or it’s a stupid question, but I have heard that using these methods are not a good way to do it in the long run. I am worried that this will not work or create problems in the future. It should be noted that without Workbooks("FUA.XLSM").Activate the code tends to create errors as it gets confused about which workbook it should select.
In short, my question is, how am I able to avoid using Select and .Activate as to mitigate potential for errors in the future?
Code is as follows..
Dim wb1 As Excel.Workbook
Dim wb2 As Excel.Workbook
Set wb2 = Workbooks.Open("C:\Users\Ha.csv")
Set wb1 = Workbooks("FUA")
Dim sht1 As Worksheet
Dim sht2 As Worksheet
Dim copyRange As Range
Set sht1 = wb1.Sheets("Sheet1")
Set sht2 = wb2.Sheets("Ha")
With wb1.Sheets("Sheet1")
Range("AA3").Select
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lastRow = .Cells.Find(What:="*", _
After:=.Range("AA3"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).row
Else
lastRow = 1
End If
End With
Workbooks("FUA.XLSM").Activate
Range("AA3").Select
sht1.ListObjects.Add(xlSrcRange, , xlYes).Name = _
"Table1"
Range("Table1[#All]").Select
sht1.ListObjects("Table1").Range.AutoFilter Field:=9, Criteria1:= _
">=-1000000000000", Operator:=xlAnd, Criteria2:="<=1000000000000000"
Application.DisplayAlerts = False
Selection.SpecialCells(xlCellTypeVisible).Copy
Application.DisplayAlerts = True
Set wb2 = Workbooks.Open("C:\Users\Ha.csv")
Application.DisplayAlerts = False
wb2.Sheets("Ha").Paste
wb2.SaveAs Filename:= _
"C:\Users\Ha.csv", FileFormat:= _
xlCSV, CreateBackup:=False
Workbooks("Ha.csv").Close
End Sub
Probably get down voted for saying this but If it ain't broke don't fix it. Your code works fine already, no real reason to change unless it doesn't work or errors popping up. Sounds like you've tested it already.
Your code is already optimised and faster though here is an alternative for the sake of avoiding Select. If you get error 1004 with select methods similar to like the last line sht2.Range("A:I").Copy Columns(last_col + 1).PasteSpecial in the code below it will continue anyway.
Sub test()
Dim wb1 As Excel.Workbook
Set wb1 = Workbooks("XXX.XLSM") ' from here, use wb1 to refer to fua.xlsm
Dim wb2 As Excel.Workbook ' ditto for wb2
Set wb2 = Workbooks.Open("C:\Users\Ha.csv")
Dim sht1 As Worksheet ' ditto for sht1
Set sht1 = wb1.Sheets("Sheet1")
Dim sht2 As Worksheet
Set sht2 = wb2.Sheets("Ha")
If Application.WorksheetFunction.CountA(sht1.Cells) <> 0 Then
LastRow = sht1.Cells.Find( _
What:="*", _
After:=sht1.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).row
Else
LastRow = 1
End If
sht1.ListObjects.Add(xlSrcRange, sht1.Range("A:I"), xlYes).Name = "Table1"
sht1.ListObjects("Table1").Range.AutoFilter _
Field:=9, _
Criteria1:=">=-1000000000000", _
Operator:=xlAnd, _
Criteria2:="<=1000000000000000"
Application.DisplayAlerts = False ' not sure if needed
sht1.Range("A:I").SpecialCells(xlCellTypeVisible).Copy
On Error Resume Next
sht2.Range("A:I").Copy Columns(last_col + 1).PasteSpecial
On Error Resume Next
Application.DisplayAlerts = True ' not sure if needed
wb2.Save ' already C:\Users\Ha.csv
wb2.Close
End Sub
Here is your code rewritten.
I think it has the same functionality.
Sub test()
Dim wb1 As Excel.Workbook
Set wb1 = Workbooks("FUA.XLSM") ' from here, use wb1 to refer to fua.xlsm
Dim wb2 As Excel.Workbook ' ditto for wb2
Set wb2 = Workbooks.Open("C:\Users\Ha.csv")
Dim sht1 As Worksheet ' ditto for sht1
Set sht1 = wb1.Sheets("Sheet1")
If Application.WorksheetFunction.CountA(sht1.Cells) <> 0 Then
LastRow = sht1.Cells.Find( _
What:="*", _
After:=sht1.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
LastRow = 1
End If
sht1.ListObjects.Add(xlSrcRange, sht1.Range("AA3"), xlYes).Name = "Table1"
sht1.ListObjects("Table1").Range.AutoFilter _
Field:=9, _
Criteria1:=">=-1000000000000", _
Operator:=xlAnd, _
Criteria2:="<=1000000000000000"
Application.DisplayAlerts = False ' not sure if needed
Range("Table1[#All]").SpecialCells(xlCellTypeVisible).Copy sht2.Cells
Application.DisplayAlerts = True ' not sure if needed
wb2.Save ' already C:\Users\Ha.csv
wb2.Close
End Sub
I wouldn't even bother with using VBA to get the data, use Power Query and import the data from the source file, perform the filter in the query and return the result to a table in the "FUA" workbook.
Then the query can be set to automatically refresh on the "FUA" workbook opening or in the query definition.
Problem: I am unable to define a range using a variable (i) and specific cells row (cell.Row).
Current Code:
Sub TaskSearch()
'Dim wb As Workbook
Dim oSht As Worksheet
Dim lastRow As Long, i As Long
Dim strSearch As String
Dim aCell As Range
ThisWorkbook.Sheets("Interface").Range("D19:D33").ClearContents
'Set wb = Workbooks.Open("H:\Kevin.Boots\Database.xlsx")
Set oSht = Sheets("TaskMaster")
lastRow = oSht.Range("A" & Rows.Count).End(xlUp).Row
strSearch = Sheets("Interface").Range("F5")
Set aCell = oSht.Range("B2:B" & lastRow).Find(What:=strSearch, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False)
Sheets("Interface").Range("D19").Value = Sheets("TaskMaster").Range("C" & aCell.Row).Value
Sheets("Interface").Range("D20").Value = Sheets("TaskMaster").Range("D" & aCell.Row).Value
Sheets("Interface").Range("D21").Value = Sheets("TaskMaster").Range("E" & aCell.Row).Value
Sheets("Interface").Range("D22").Value = Sheets("TaskMaster").Range("F" & aCell.Row).Value
Sheets("Interface").Range("D23").Value = Sheets("TaskMaster").Range("G" & aCell.Row).Value
Sheets("Interface").Range("D24").Value = Sheets("TaskMaster").Range("H" & aCell.Row).Value
Sheets("Interface").Range("D25").Value = Sheets("TaskMaster").Range("I" & aCell.Row).Value
Sheets("Interface").Range("D26").Value = Sheets("TaskMaster").Range("J" & aCell.Row).Value
Sheets("Interface").Range("D27").Value = Sheets("TaskMaster").Range("K" & aCell.Row).Value
Sheets("Interface").Range("D28").Value = Sheets("TaskMaster").Range("L" & aCell.Row).Value
Sheets("Interface").Range("D29").Value = Sheets("TaskMaster").Range("M" & aCell.Row).Value
Sheets("Interface").Range("D30").Value = Sheets("TaskMaster").Range("N" & aCell.Row).Value
Sheets("Interface").Range("D31").Value = Sheets("TaskMaster").Range("O" & aCell.Row).Value
Sheets("Interface").Range("D32").Value = Sheets("TaskMaster").Range("P" & aCell.Row).Value
Sheets("Interface").Range("D33").Value = Sheets("TaskMaster").Range("Q" & aCell.Row).Value
Exit Sub
End Sub
Objective: I am attempting to make this code more robust. Part of reasoning is for me to be able to skip blanks. This is a nightmare when trying to adjust cells.
I have tried two different methods to accomplish this:
Method A:
wb.Sheets("Interface").Range("D19:D33").Copy
wb.Sheets("TaskMaster").Range("C" & aCell.Row & ":Q" & aCell.Row).PastSpecial Paste:=xlPasteValues, SkipBlanks:=True
Failure: Runtime Error 438: Object doesn't support this property or method.
Method B:
For j = 3 To 16
If Not IsEmpty(j, aCell.Row) Then
For i = 19 To 33
iWb.oSht.Range(j, aCell.Row).Value = _
iWb.iSht.Range(4, i).Value
Next i
End If
Next j
Exit Sub
Failure: ( I cant get this older version to compile again) I believe the error arose with issues defining the range.
To summarize I am trying to find the fastest method to transfer information from one worksheet to another worksheet using the .find. I am also trying to not copy blank cells while transferring.
I currently believe this method will be the best suited for my application.
Sub TSearch()
Dim dWb As Workbook, Wb As Workbook
Dim oSht As Worksheet, Sht As Worksheet
Dim lastRow As Long, i As Long, j As Long
Dim strSearch As String
Dim aCell As Variant
Dim cell As Variant
'On Error GoTo Err
ThisWorkbook.Sheets("Interface").Range("D19:D33").ClearContents
'Set dWb = Workbooks.Open("H:\Kevin.Boots\Database.xlsx")
Set Wb = ThisWorkbook
Set Sht = Sheets("TaskMaster") ' Reference Worksheet
Set oSht = Sheets("Interface") ' User Interface Worksheet
lastRow = Sht.Range("A" & Rows.Count).End(xlUp).Row 'Obtain Last row of reference Worksheet
strSearch = oSht.Range("F5") 'Obtain User Selected Search Criteria
Set aCell = Sht.Range("B2:B" & lastRow).Find(What:=strSearch, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False)
For j = 3 To 16 'Columns from Reference Worksheet to be transfered
If Not IsEmpty(Wb.Sht.Cells(aCell.Row, j)) Then ' Verify If cell has value before transfering
For i = 19 To 33 ' Rows of User Interface where values are to be transfered
Wb.Sht.Cells(aCell.Row, j).Value = _
Wb.oSht.Cells(i, 4).Value
Next i
End If
Next j
Exit Sub
'Err: 'MsgBox " Generic Task not found" & vbCrLf
End Sub
The IEmpty Function is still causing an error 438: Object doesn't support this property method. If I remove the IsEmpty then
'Wb.Sht.Cells(aCell.Row, j).Value = Wb.oSht.Cells(i, 4).Value' gives me the same error.
Your loop won't work due to IsEmpty which expects a single cell or variable to check, but you are giving it two numbers. The below should work, but some things aren't qualified, so you may still run into issues. Also, Range() expects either two ranges to be provided, or a range string. I think you were looking for Cells(), which accepts a row (as a number) as the first parameter and a column (as a number) as the second.
For j = 3 To 16
If Not IsEmpty(cells(aCell.Row, j)) Then
For i = 19 To 33
iWb.oSht.Cells(aCell.Row, j).Value = _
iWb.iSht.Cells(4, i).Value
Next i
End If
Next j
End Sub
It appears the errors were a result of trying to define something that was defined.
Sub TSearch()
Dim dWb As Workbook, Wb As Workbook
Dim oSht As Worksheet, Sht As Worksheet
Dim lastRow As Long, i As Long, j As Long
Dim strSearch As String
Dim aCell As Variant
Dim cell As Variant
'On Error GoTo Err
ThisWorkbook.Sheets("Interface").Range("D19:D33").ClearContents
'Set dWb = Workbooks.Open("H:\Kevin.Boots\Database.xlsx")
Set Wb = ThisWorkbook
Set Sht = Sheets("TaskMaster") ' Reference Worksheet
Set oSht = Sheets("Interface") ' User Interface Worksheet
lastRow = Sht.Range("A" & Rows.Count).End(xlUp).Row 'Obtain Last row of reference Worksheet
strSearch = oSht.Range("F5") 'Obtain User Selected Search Criteria
'Find Row in Reference Worksheet that Matches Search Criteria
Set aCell = Sht.Range("B2:B" & lastRow).Find(What:=strSearch, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False)
For j = 3 To 16
If Not IsEmpty(Cells(aCell.Row, j)) Then
i = j + 16
oSht.Cells(i, 4).Value = Cells(aCell.Row, j).Value
End If
Next j
Exit Sub
'Err:
'MsgBox " Generic Task not found" & vbCrLf
End Sub
Thank you to #Jordan and #Kyle for helping solve this issue.
I am using data from two different sources. Each source has formatted their date/time differently. I need to put both sets of data into one worksheet and remove duplicates. The date format differences is preventing this. I am trying to copy the date format from workbook "A" to a column range of existing data in workbook "B" so that when I copy the data over from workbook "A" to the end of workbook "B", the date formats will match.
The date format in workbook "A" is:
The Date format in workbook "B" is:
I have supplied the entire code below. But here is the line I have added:
sourceWorksheet.Range("G2").Copy destinationWorksheet.Range("G2:H2000").PasteSpecial(xlPasteFormats, Operation:=xlNone, SkipBlanks:=False)
Which gives me the following error:
Run-time error '1004':
Unable to get the PasteSpecial property of the Range class
Here is the entire code set:
Sub QA_1603_March()
'
Dim ANS As Long
Dim LR As Long
Dim uRng As Range
Dim she As Worksheet
ANS = MsgBox("Is the March 2016 Swivel Master File checked out of SharePoint and currently open on this desktop?", vbYesNo + vbQuestion + vbDefaultButton1, "Master File Open")
If ANS = vbNo Or IsWBOpen("Swivel - Master - March 2016") = False Then
MsgBox "The required workbook is not currently open. This procedure will now terminate.", vbOKOnly + vbExclamation, "Terminate Procedure"
Exit Sub
End If
Call Verification_Format_WS
Dim sourceWorkBook As Workbook
Set sourceWorkBook = Workbooks("Verification Temp.xlsx")
Dim destinationWorkbook As Workbook
Set destinationWorkbook = Workbooks("Swivel - Master - March 2016.xlsm")
Dim sourceWorksheet As Worksheet
Set sourceWorksheet = sourceWorkBook.Sheets("Verification")
Dim destinationWorksheet As Worksheet
Set destinationWorksheet = destinationWorkbook.Sheets("Validation")
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
sourceWorksheet.Cells.EntireRow.Hidden = False
sourceWorksheet.Range("G2").Copy destinationWorksheet.Range("G2:H2000").PasteSpecial(xlPasteFormats, Operation:=xlNone, SkipBlanks:=False)
For LR = sourceWorksheet.Range("J" & Rows.Count).End(xlUp).row To 2 Step -1
If sourceWorksheet.Range("J" & LR).Value <> "3" Then
If uRng Is Nothing Then
Set uRng = sourceWorksheet.Rows(LR)
Else
Set uRng = Union(uRng, sourceWorksheet.Rows(LR))
End If
End If
Next LR
If Not uRng Is Nothing Then uRng.Delete
For Each she In destinationWorkbook.Worksheets
If she.FilterMode Then she.ShowAllData
Next
With sourceWorksheet.Sort
With .SortFields
.Clear
.Add Key:=Range("A2:A2000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Add Key:=Range("G2:G2000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Add Key:=Range("B2:B2000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Add Key:=Range("C2:C2000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Add Key:=Range("D2:D2000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Add Key:=Range("E2:E2000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
End With
.SetRange Range("A2:AE2000")
.Apply
End With
sourceWorksheet.Cells.WrapText = False
Dim lastRow As Long
lastRow = sourceWorksheet.Range("A" & Rows.Count).End(xlUp).row
Dim destinationRow As Long
destinationRow = destinationWorksheet.Cells(Rows.Count, 1).End(xlUp).row + 1
sourceWorksheet.Range("A2:J" & lastRow).Copy destinationWorksheet.Range("A" & destinationRow)
Call Verification_Save
Call Verification_Delete_Temp_Workbook
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
End Sub
I have tried a few variations of this from examples I have found here, but I keep getting errors of one kind or another.
As #Scott said, the copy line needs to be split into two lines. However, you do not need the Operation:=xlNone, SkipBlanks:=False parts because by default they will be set to that. The following should work.
sourceWorksheet.Range("G2").Copy
destinationWorksheet.Range("G2:H2000").PasteSpecial xlPasteFormats
*Note: You don't need the parenthesis to pass the parameter in this case.
The problem is the line:
sourceWorksheet.Range("G2").Copy destinationWorksheet.Range("G2:H2000").PasteSpecial(xlPasteFormats, Operation:=xlNone, SkipBlanks:=False)
is invalid syntax.
The Copy method has an optional argument to pass a Range object as the destination. By adding the PasteSpecial method to the range, this ceases to be valid.
Try this:
sourceWorksheet.Range("G2").Copy
destinationWorksheet.Range("G2:H2000").PasteSpecial(xlPasteFormats, Operation:=xlNone, SkipBlanks:=False)
I was trying to compare two different Workbooks, one named "after" (which is up to date) and another called "before" and I wanted to highlight the differences so it would be easy to pin down what changed between the two.
Okay so after I tested it a bit I got stuck in an error
"Object doesn't support this property or method".
Here's the full code with added comments so you can follow my thought process:
Sub OpenCsv()
Dim zcf, FolderPath, after, before, shtAfter, shtBefore As String
Dim MotherWB As Workbook, MotherWS As Worksheet
Dim wb As Workbook, ws, worksheetz As Worksheet
Dim oneRange, aCell As Range
Dim rng As Range
Dim Answer As Integer
Dim mycell As Range
Dim mydiffs As Integer
'Sorts Things for MotherWB
Set oneRange = Range("A4:Z9000")
Set aCell = Range("F4")
oneRange.Sort Key1:=aCell, Order1:=xlAscending, Header:=xlYes
'Opens and sets both Workbooks with their respective sheets
FolderPath = Application.ActiveWorkbook.Path
after = FolderPath + "\" + "after.csv"
before = FolderPath + "\" + "before.xlsm"
Workbooks.Open (after)
Set wb = Workbooks("after.csv")
Set ws = wb.Worksheets("after")
Set MotherWB = Workbooks("before.xlsm")
Set MotherWS = MotherWB.Worksheets("before")
'Makes ws looks like MotherWS so we compare them
With ws
Columns("A:Z").AutoFit
Selection.TextToColumns _
Destination:=Range("A1:A9000"), _
DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, _
ConsecutiveDelimiter:=False, _
Tab:=False, _
Semicolon:=False, _
Comma:=True, _
Space:=False, _
Other:=False
Set oneRange = Range("A4:Z9000")
Set aCell = Range("F4")
oneRange.Sort Key1:=aCell, Order1:=xlAscending, Header:=xlYes
End With
'Questions if you want to compare both
Answer = MsgBox("Uma vez aberto o relatório deseja comparar os dois?", vbYesNo + vbQuestion, "Comparar")
If Answer = 6 Then
'For each cell in after that is not the same in before, color it yellow
For Each mycell In wb.ws(after).UsedRange
If Not mycell.Value = MotherWB.MotherWS(before).Cells(mycell.row, mycell.Column).Value Then
mycell.Interior.Color = vbYellow
mydiffs = mydiffs + 1
End If
Next
'Display a message box to demonstrate the differences
MsgBox mydiffs & " differences found", vbInformation
ActiveWorkbook.Sheets(after).Select
End If
End Sub
It gets the error after I return 6 from the answer, saying what I stated above. What am I doing wrong?
Answer is set as boolean and the msgbox will return a integer. Declare an integer and then use an if statement to put true/false in your answer variable. Something similar to below
Dim temp as integer
temp = MsgBox("Uma vez aberto o relatório deseja comparar os dois?", vbYesNo + vbQuestion, "Comparar")
if temp = 6 then
Answer = true
else
Answer = false
endif
If I set the initial part of my range as Range("A:A"), how do I make sure the entire row is passed to the sort?
Data
id, fname, mname, lname, suffix, state, location, timezone
The range is selected by searching id for a starting point and an ending point.
Thus Range might be A1:183 on one sheet and A1:A1138 on another. And the columns end on either G or H. Data still needs "massaging"
On each sheet I'm sorting by D(lname) and B(fname) and I want to include the remaining columns, so the data integrity is preserved.
So far I have a sub that selects the range, but I don't know how to tag on the additional columns without rng.EntireRow.Select, which doesn't seem to be working.
Sub sortRows(bodyName As String, ByRef wksht As Worksheet)
Dim operationalRange As Range, sortRange As Range
Set operationalRange = selectBodyRow(bodyName).EntireRow
Debug.Print "Sorting Worksheet " & wksht.Name & " containing " & operationalRange.Count & " rows."
ActiveWorkbook.Worksheets(wksht.Name).Sort.SortFields.Clear
ActiveWorkbook.Worksheets(wksht.Name).Sort.SortFields.Add Key:=operationalRange, _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets(wksht.Name).Sort.SortFields.Add Key:=operationalRange, _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets(wksht.Name).Sort
.SetRange operationalRange
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply ' Fails here with:
' Runtime Error '1004':
' The sort reference is not valid. Make sure that it's within the data
' you want to sort, and the first Sort By box isn't the same or blank.
End With
End Sub
You need to find the Last Row and and the Last Column to construct your range.
For example
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim LRow As Long, LCol As Long
Dim rng As Range
'~~> Change this with thee relevant sheet name
Set ws = ThisWorkbook.Sheets("Sheet1")
'~~> Get Last Row and Last Column
LRow = LastRow(ws)
LCol = LastColumn(ws)
With ws
'~~> Define your range
Set rng = .Range("A1:" & ReturnName(LCol) & LRow)
Debug.Print rng.Address
End With
End Sub
'~~> Function to get last row
Public Function LastRow(Optional wks As Worksheet) As Long
If wks Is Nothing Then Set wks = ActiveSheet
LastRow = wks.Cells.Find(What:="*", _
After:=wks.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
End Function
'~~> Function to get last column
Public Function LastColumn(Optional wks As Worksheet) As Long
If wks Is Nothing Then Set wks = ActiveSheet
LastColumn = wks.Cells.Find(What:="*", _
After:=wks.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
End Function
'~~> Function to get the Column name from Column Number
Function ReturnName(ByVal num As Integer) As String
ReturnName = Split(Cells(, num).Address, "$")(1)
End Function