Run time error: 424 : Object required when I try to reach range and use range data - vba

I am trying to highligh new excel the same way as old excel and data is large .So I saved the data in range and tried to do find, count if functions in range .But it keep showing "object not find error".I really don't get it since I defined the range object well. Here are part of my codes .I tried to debug by "RangSe1(1, 1).Activate" after I defined the RangSe1 object and it give me the 424 error even from here . I am really confused .
Sub Morningsmall()
Dim strfile As String
Dim iLastrow, iColor, iFind, iLastrow1, iLastrow2, iLastrow3, iLastrow4, iRow As Long
Dim RangSe1, RangSo1, RangSe2, RangSo2, RangS As Range
Dim wbLastday, wbToday As Workbook
Dim wsSettle1, wsSettle2, wsSophis1, wsSophis2 As Worksheet
With Application
.ScreenUpdating = False
.EnableEvents = False
.Calculate
.Calculation = xlCalculationManual
.DisplayStatusBar = False
End With
'Open yesterday's file
MsgBox "Open Yesterday's Settlement Report"
strfile = Application.GetOpenFilename
If strfile <> "False" Then Workbooks.Open strfile
Set wbLastday = ActiveWorkbook
Set wsSettle1 = wbLastday.Sheets("SettlementReport")
Set wsSophis1 = wbLastday.Sheets("Sophis")
iLastrow1 = wsSettle1.Cells(wsSettle1.Rows.Count, 1).End(xlUp).Row
iLastrow2 = wsSophis1.Cells(wsSophis1.Rows.Count, 1).End(xlUp).Row
RangSe1 = wsSettle1.Range("A1:AQ" & iLastrow1)
RangSo1 = wsSophis1.Range("A1:AJ" & iLastrow2)
RangSe1(1, 1).Activate
...
...
...
For i = 2 To iLastrow3
iFind = RangSe2(i, 1)
'a = Application.WorksheetFunction.CountIf(Rang, iFind)
If Application.WorksheetFunction.CountIf(wsSettle1, iFind) > 0 Then
'range1.Find("test id", LookIn:=xlValues)
If RangSe1(wsSettle1.Cells.Find(what:=iFind).Row, 6) = RangSe2(i, 6) Then
iColor = RangSe1.Find(what:=iFind).Interior.Color
If iColor <> 16777215 Then
wsSettle2.Rows(i).Interior.Color = iColor
End If
End If
End If
...
...
...

Your lines saying
Dim RangSe1
'...
RangSe1 = wsSettle1.Range("A1:AQ" & iLastrow1)
is equivalent to
Dim RangSe1 As Variant
'...
RangSe1 = wsSettle1.Range("A1:AQ" & iLastrow1).Value
which will create a Variant array dimensioned as 1 To iLastrow1, 1 To 43. You can't use an Activate method on the (1, 1)th position of an array, because an array is not an object and therefore does not have methods or properties.
You have two major mistakes that are causing your code to not do what you expect:
1) You are not defining your variables correctly because:
Dim RangSe1, RangSo1, RangSe2, RangSo2, RangS As Range
is equivalent to :
Dim RangSe1 As Variant, RangSo1 As Variant, RangSe2 As Variant, RangSo2 As Variant, RangS As Range
You should use:
Dim RangSe1 As Range, RangSo1 As Range, RangSe2 As Range, RangSo2 As Range, RangS As Range
2) You are not using the Set keyword when assigning a reference to your Range objects so, for instance,
RangSe1 = wsSettle1.Range("A1:AQ" & iLastrow1)
should be
Set RangSe1 = wsSettle1.Range("A1:AQ" & iLastrow1)

Related

Add separate columns into a dictionary

I am trying to add data from a split range (X5:X?,AX5:AX?) into a VBA dictionary. ? Is determined as the last row of data within the sheet. I am new to VBA and trying to force my way through this.
Public Sub Test
'Creates a dictionary object
Dim orderstatus As Object, path As String
Set orderstatus = CreateObject("Scripting.Dictionary")
Dim order, status 'key and object names
order = "Order #": status = "Order Status"
path = ThisWorkbook.path
'Central District--A Head Water Order Summary
Dim app As New Excel.Application, book As Excel.Workbook
app.Visible = False
Set book = app.Workbooks.Add(path & "\CENTRAL DIST\A HEAD - WATER ORDER SUMMARY.xls")
'A Head #1
Dim A1Head As Integer, last As Integer, l as Integer
l = 4
book.Worksheets("A HEAD #1").Activate
last = Range("X" & Rows.Count).End(xlUp).Row
Set lastCol = Range("X5:X" & last, "AX5:AX" & last)
For Each l In lastCol.Cells
orderstatus.Add lastCol.Value
Next
End Sub
Any help is greatly appreciated!
I think something like this is what you're looking for:
Sub tgr()
Dim OrderStatus As Object
Dim i As Long
Dim Key As Variant
Set OrderStatus = CreateObject("Scripting.Dictionary")
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
With Workbooks.Open(ThisWorkbook.Path & "\CENTRAL DIST\A HEAD - WATER ORDER SUMMARY.xls").Sheets("A HEAD #1")
For i = 5 To .Cells(.Rows.Count, "X").End(xlUp).Row
If Not OrderStatus.Exists(.Cells(i, "X").Value) Then OrderStatus(.Cells(i, "X").Value) = .Cells(i, "AX").Value
Next i
.Parent.Close False
End With
'Print dictionary to text file
Close #1
Open ThisWorkbook.Path & "\OrderStatus Output.txt" For Output As #1
Print #1, "Key" & vbTab & "Value"
For Each Key In OrderStatus.Keys
Print #1, Key & vbTab & OrderStatus(Key)
Next Key
Close #1
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Change this
orderstatus.Add lastCol.Value
to this
orderstatus.Add l.Value, 1
This assumes you will have no duplicates because you aren't checking for that and will get an error if you do have duplicates.
you're messing up with Range object and Row index
and you'd better abandon the Activate/ActiveXXX pattern and use fully qualified range references
give this code a try
Option Explicit
Public Sub Test()
'Creates a dictionary object
Dim orderstatus As Object
Set orderstatus = CreateObject("Scripting.Dictionary")
'Central District--A Head Water Order Summary
Dim app As New Excel.Application, book As Excel.Workbook
app.Visible = False
Set book = app.Workbooks.Add(ThisWorkbook.path & "\CENTRAL DIST\A HEAD - WATER ORDER SUMMARY.xls")
'A Head #1
Dim dataRng As Range, r As Range
Dim last As Integer
With book.Worksheets("A HEAD #1")
For Each r In .Range("X5", .Cells(.Rows.Count, "X").End(xlUp))
orderstatus(r.value) = r.Offset(, 26).value
Next
End With
End Sub
Moreover if you're running this macro from within an Excel session already, you don't need to get another instance of it nor explicitly reference it:
Option Explicit
Public Sub Test()
'Creates a dictionary object
Dim orderstatus As Object
Set orderstatus = CreateObject("Scripting.Dictionary")
'Central District--A Head Water Order Summary
Dim book As Workbook
Set book = Workbooks.Add(ThisWorkbook.path & "\CENTRAL DIST\A HEAD - WATER ORDER SUMMARY.xls")
'A Head #1
Dim dataRng As Range, r As Range
Dim last As Integer
With book.Worksheets("A HEAD #1")
For Each r In .Range("X5", .Cells(.Rows.Count, "X").End(xlUp))
orderstatus(r.value) = r.Offset(, 26).value
Next
End With
End Sub

PasteSpecial Method Odd Error

I have gone through the similar questions and have not found anything with this specific error.
I am trying to make a macro that goes through a large number of CSV files, pulls the necessary information I need, copies and pastes that data to a new Workbook, and then closes the CSV file and goes to the next one.
When I test my code and have it run Step by Step (using F8) it functions fine and there are no error. However, whenever I try and just have the code run (like pressing F5) I get the error "PasteSpecial Method of Class Range" failed. When I press debug this line of the code is highlighted:
copyRange.Offset(0, 1).PasteSpecial Paste:=xlPasteValues
I added a small time delay of 0.5s before this line and it actually was able to go further through the files before failing.
Is it something with the Range.Offset method? Should I explicitly define a different copy range?
Code I have follows below:
Public Sub OpenTXT_CopyNewWBK(inPath As String)
Application.ScreenUpdating = False
Dim fso, oFolder, oSubfolder, oFile, queue As Collection
Dim app As New Excel.Application
app.Visible = True
Dim dataRange As Range, dateRange As Range, copyRange As Range
Dim lastCell, lastRow As String
Dim newBook, wbk As Excel.Workbook
Dim csvStart As Long
Set newBook = Workbooks.Add
With newBook
.SaveAs Filename:="BETA RAY " & Format(Now, "ddmmyyhhmmss")
End With
Set fso = CreateObject("Scripting.FileSystemObject")
Set queue = New Collection
queue.Add fso.GetFolder(inPath) 'obviously replace
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
Do While queue.Count > 0
Set oFolder = queue(1)
queue.Remove 1 'dequeue
For Each oSubfolder In oFolder.SubFolders
queue.Add oSubfolder 'enqueue
Next oSubfolder
For Each oFile In oFolder.Files
Set wbk = app.Workbooks.Add(oFile.Path)
lastCell = wbk.Sheets(1).Range("A1").End(xlDown).Address
If Len(lastCell) = 6 Then
lastRow = Mid(lastCell, 4, 3)
ElseIf Len(lastCell) = 5 Then
lastRow = Mid(lastCell, 4, 2)
ElseIf Len(lastCell) = 4 Then
lastRow = Mid(lastCell, 4, 1)
End If
Set dateRange = wbk.Sheets(1).Range("A2", lastCell)
dateRange.Select
Set dataRange = wbk.Sheets(1).Range("AA2", "AM" & lastRow)
dataRange.Select
wbk.Application.CutCopyMode = True
Set copyRange = Workbooks(newBook.name).Sheets(1).Range("A1048576").End(xlUp)
If Not copyRange = "" Then
Set copyRange = copyRange.Offset(1, 0)
End If
dateRange.Copy
copyRange.PasteSpecial Paste:=xlPasteValues
wbk.Application.CutCopyMode = False
wbk.Application.CutCopyMode = True
Application.Wait (Now + 500 * 0.00000001)
dataRange.Copy
copyRange.Offset(0, 1).PasteSpecial Paste:=xlPasteValues
wbk.Application.CutCopyMode = False
wbk.Close SaveChanges:=False
Next oFile
Loop
app.Quit
Set app = Nothing
Range("B:B").Delete
Range("G:G").Delete
Range("L:L").Delete
Application.ScreenUpdating = True
End Sub
I am sure there are much better ways to do a lot of the things I have going on there. I really just use VBA to make my life easier at work so a lot of the code I use is copy, pasted, and modified to fit my needs. I couldn't figure out how to make this method work wbk2.sht2.Range("A1:A5") = wbk1.sht1.Range("B1:B5") everything I have read says this should be a much better method. Also, the portions of code that read dataRange.Select and dateRange.Select are just there for debugging purposes.
try this....
wbk2.sht2.Range("A1:A5").value = wbk1.sht1.Range("B1:B5").value

VBA: Display "NA" in cell on error

With below code I am calculating the RSS. It does however happen that the Y range does not actually contain values. I have surpassed the error (Run-time error '1004') that displays when there aren't any values with 'on error goto next' but then it just 'copies' the same value as the previous one in the destination cell when there wouldn't actually be any.
Is there a way to display "NA" in stead of the previous value in the destination cell where the RSS cannot be calculated due to a lack of Y values?
Thank you in advance
Private Sub Regr(strWksData As String, WsTools As Worksheet, strWksFF3 As String, strWksResult As String)
Dim NoOfRow As Long
Dim i As Integer
Dim sData As Worksheet
Dim sFF3 As Worksheet
Dim sResult As Worksheet
Dim rX1 As Range
Dim rY1 As Range
'General
Set sData = Sheets("Return")
Set sFF3 = Sheets("FF-3")
Set sResult = Sheets("Result")
'Set X ranges
Set rX1 = sFF3.Range("C2:E21")
'Set Y ranges
Set rY1 = sData.Range("F2:F21")
'Loop through columns
'Provide statistic
On Error GoTo ErrorHandling
For i = 0 To 5
vStat1 = Application.WorksheetFunction.LinEst(rY1.Offset(0, i), rX1, True, True)
sResult.Range("F2").Offset(0, i).Value = vStat1(5, 2)
NoOfRow = rY1.Rows.Count
WsTools.Range("B2").Value = NoOfRow
Next i
ErrorHandling:
Resume Next
On Error GoTo 0
MsgBox ("RSS Done")
End Sub
Since you are writing the results directly to the worksheet, just take advantage of the different error reporting behavior of Application.LinEst v. Application.WorksheetFunction.LinEst.
When you call the fully qualified WorksheetFunction, any error raised in the called function is thrown as a run-time error:
Debug.Print Application.WorksheetFunction.Sum("a", "b") '<--runtime error 1004
When you use the extensible interface on Application, any error raised in the called function is returned wrapped in a Variant:
Debug.Print Application.Sum("a", "b") '<--Prints Error 2015 (#VALUE!)
If you need to test to see whether or not it's an error, you can use the IsError function:
Dim v As Variant
v = Application.Sum("a", "b")
Debug.Print IsError(v) '<-- True
In your case, you can just write the error value directly to the cell:
For i = 0 To 5
Dim result As Variant
result = Application.LinEst(rY1.Offset(0, i), rX1, True, True)
'Don't attempt to use the indexer on an error.
If IsError(result) Then
sResult.Range("F2").Offset(0, i).Value = result
Else
sResult.Range("F2").Offset(0, i).Value = result(5, 2)
End If
Next

Copy named ranges to the active sheet

I'm trying to copy named ranges from the Wk1 worksheet to the active sheet in the workbook.
I keep getting error messages when I run the code. They either say an Object is not set or a variable has not been declared.
Sub ChangeNamedRangesOnNewWKsheet()
Dim RangeName As Name
Dim HighlightRange As Range
Dim RangeName2 As String
Dim NewRangeName As String
Dim Ws As Worksheets
Dim cs As Worksheet
Set cs = Application.ActiveSheet
''''' Delete invalid named ranges
For Each RangeName In ActiveWorkbook.Names
If InStr(1, RangeName.RefersTo, "#REF!") > 0 Then
RangeName.Delete
End If
Next RangeName
For Each RangeName In Ws
If InStr(1, RangeName, "Wk1", 1) > 0 Then
Set HighlightRange = RangeName.RefersToRange
NewRangeName = Replace(RangeName.Name, "Wk1", "cs.Name")
RangeName2 = Replace(RangeName, "='Wk1'", "'cs.Name'")
On Error Resume Next
HighlightRange.Copy Destination:=Worksheets("cs.Name").Range(RangeName2)
Range(RangeName2).Name = NewRangeName
On Error GoTo 0
End If
Next RangeName
MsgBox "Done"
End Sub
Ive changed the code to this. Im not getting error messages but the code is still not working. the named ranges are not copying from the Wk1 sheet to the Active sheet. The only thing that happens is that the Message Box Opens
Sub ChangeNamedRangesOnNewWKsheet()
Dim RangeName As Name
Dim HighlightRange As Range
Dim RangeName2 As String
Dim NewRangeName As String
Dim Cs As Worksheet
Set Cs = Application.ActiveSheet
''''' Delete invalid named ranges
For Each RangeName In ActiveWorkbook.Names
If InStr(1, RangeName.RefersTo, "#REF!") > 0 Then
RangeName.Delete
End If
Next RangeName
For Each RangeName In ActiveWorkbook.Names
If InStr(1, RangeName, "Wk1", 1) > 0 Then
Set HighlightRange = RangeName.RefersToRange
NewRangeName = Replace(RangeName.Name, "Wk1", "cs.Name")
RangeName2 = Replace(RangeName, "='Wk1'", "'cs.Name'")
On Error Resume Next
HighlightRange.Copy Destination:=Worksheets("cs.Name").Range(RangeName2)
Range(RangeName2).Name = NewRangeName
On Error GoTo 0
End If
Next RangeName
MsgBox "Done"
End Sub
Took me some time to figure out whats not working when there is no error, but finally I think I managed to figure out the issue.
Replace the following line in your code
HighlightRange.Copy Destination:=Worksheets("cs.Name").Range(RangeName2)
to:
HighlightRange.Copy Destination:=Worksheets(cs.Name).Range(HighlightRange.Address)
This should give you desired result.
Syntax for Copy to destination is Destination:=Worksheets("sheet_name").Range(range). Here sheet_name should be the name of the sheet. So when you write Worksheets("cs.Name") code looks for the sheet named cs.Name which actually does not exist hence just use Worksheets(cs.Name). Second thing here is range (just to explain things better I am using $A$1:$A$5 as range). When you write .Range(RangeName2) code is looking for 'cs.Name'!$A$1:$A$5. Again this is incorrect because range should be written as .Range($A$1:$A$5). So .Range(HighlightRange.Address) will give you the proper range.
You can also play out in the line RangeName2 = Replace(RangeName, "='Wk1'", "'cs.Name'") to get proper address.
Hope this helps.
EDIT :
__________________________________________________________________________________
example of what i want. copy the named range Wk1Totalhrs from Wk1 sheet to Wk2-Wk7 sheets so that Wk1Totalhrs becomes Wk2Totalhrs,Wk3Totalhrs etc on the corresponding new sheet
Try the following code to achieve what you mentioned as your requirement in comment (or as above).
Sub ChangeNamedRangesOnNewWKsheet()
Dim RangeName As Name
Dim HighlightRange As Range
Dim RangeName2 As String, NewRangeName As String, SearchRange As String
Dim MyWrkSht As Worksheet, cs As Worksheet
Set MyWrkSht = ActiveWorkbook.Worksheets("Wk1")
SearchRange = "Wk1Totalhrs" '---> enter name of the range to be copied
''''' Delete invalid named ranges
For Each RangeName In MyWrkSht.Names
If InStr(1, RangeName.RefersTo, "#REF!") > 0 Then
RangeName.Delete
End If
Next RangeName
'For Each RangeName In MyWrkSht.Names ActiveWorkbook.Names
For Each RangeName In ActiveWorkbook.Names
If RangeName.Name = SearchRange Then '---> search for the named range Wk1Totalhrs
Set HighlightRange = RangeName.RefersToRange
For Each cs In ActiveWorkbook.Sheets
Debug.Print cs.Name
If cs.Name <> "Wk1" Then '---> don't do anything in the sheet Wk1
NewRangeName = Replace(RangeName.Name, "Wk1", cs.Name)
RangeName2 = Replace(RangeName, "='Wk1'", cs.Name)
HighlightRange.Copy Destination:=Worksheets(cs.Name).Range(HighlightRange.Address)
Range(RangeName2).Name = NewRangeName
End If
Next cs
End If
Next RangeName
End Sub
I think it's just as simple as this.
Public Sub ShowNames()
Dim Nm As Name
Dim i As Long
For Each Nm In ActiveWorkbook.Names
i = i + 1
Range("A1").Offset(i, 0).Value = Nm
Next Nm
End Sub
Im not getting error messages but the code is still not working.the named ranges are not copying from the Wk1 sheet to the Active sheet.
The following line will return false positives when the named range starts with or contains WK10, WK11, etc.
If InStr(1, RangeName, "Wk1", 1) > 0 Then
A little further down, you are quoting a variable property; this makes it a literal string, not the value of the variable property.
NewRangeName = Replace(RangeName.Name, "Wk1", "cs.Name")
You need a more concrete way to identify the defined names on WK1. After looking closely at your problem, I believe that you may have one or more dynamic named ranges that are defined by formulas. This would explain some of the 'not working' behavior of your code that should be working with more conventional ReferTo: properties.
There is also the problem of whether you should rewrite the RefersTo: of an existing defined named range or add a new named range. One common practise is to simply attempt to delete the named range un On Error Resume Next and then create a new one. I've never liked this method for a variety of reasons; one being that deleting a named range will make dependent named ranges refer to #REF! and I've never considered on error resume next to be a 'best practise'.
The following builds a dictionary of keys containing named ranges to be created and ones that already exist using multiple criteria. I've tested this repeatedly on a combination of conventional and dynamic named ranges with success.
Option Explicit
Sub ChangeNamedRangesOnNewWKsheet()
Dim nm As Name
Dim rtr As String, nm2 As String
Dim w As Long
Dim k As Variant, dict As Object
Set dict = CreateObject("Scripting.Dictionary")
dict.comparemode = vbTextCompare
With ActiveWorkbook
'Delete invalid named ranges and build dictionary of valid ones from WK1
For Each nm In .Names
If CBool(InStr(1, nm.RefersTo, "#REF!", vbTextCompare)) Or _
CBool(InStr(1, nm.RefersTo, "#NAME?", vbTextCompare)) Then
'Debug.Print nm.Name
On Error Resume Next
nm.Delete
Err.Clear
On Error GoTo 0
ElseIf LCase(Left(nm.Name, 3)) = "wk1" And _
(CBool(InStr(1, nm.RefersTo, "wk1!", vbTextCompare)) Or _
CBool(InStr(1, nm.RefersTo, "'wk1'!", vbTextCompare))) Then
dict.Item(Mid(nm.Name, 4)) = LCase(nm.RefersTo)
ElseIf LCase(Left(nm.Name, 2)) = "wk" Then
dict.Item(nm.Name) = LCase(nm.RefersTo)
End If
Next nm
For w = 1 To Worksheets.Count
With Worksheets(w)
If LCase(.Name) <> "wk1" And Left(LCase(.Name), 2) = "wk" Then
For Each k In dict
If dict.exists(.Name & k) Then
.Parent.Names(.Name & k).RefersTo = _
Replace(LCase(dict.Item(k)), "wk1", .Name, 1, -1, vbTextCompare)
ElseIf Left(LCase(k), 2) <> "wk" Then
.Parent.Names.Add _
Name:=.Name & k, _
RefersTo:=Replace(LCase(dict.Item(k)), "wk1", .Name, 1, -1, vbTextCompare)
End If
Next k
End If
End With
Next w
End With
dict.RemoveAll: Set dict = Nothing
'MsgBox "All worksheets done"
End Sub
Note that this creates/redefines all named ranges on all worksheets (other than WK1). As far as I can determine, the only chance to have false positives would be to have an existing named range with a name something like WK1wkrange (but that would just be silly).
This code works
Public Sub CopyNamedRanges()
Dim namedRange As Name
Dim targetRefersTo As String
Dim targetName As String
On Error Resume Next
For Each namedRange In ActiveWorkbook.Names
If Left$(namedRange.RefersTo, 6) = "='Wk1'" And Left$(namedRange.Name, 3) = "Wk1" Then
targetName = Replace(namedRange.Name, "Wk1", ActiveSheet.Name)
targetRefersTo = Replace(namedRange.RefersTo, "Wk1", ActiveSheet.Name)
ActiveWorkbook.Names.Add targetName, targetRefersTo ' Might error if it already exists
ActiveWorkbook.Names(targetName).RefersTo = targetRefersTo
namedRange.RefersToRange.Copy Range(targetName) ' Remove this line if it's not required
End If
Next
End Sub
How the code works
This part If Left$(namedRange.RefersTo, 6) = "='Wk1'"
makes sure that the range refers to some cells on the sheet called Wk1
The other condition (Left$(namedRange.Name, 3) = "Wk1") would also match named ranges on sheets Wk10 - Wk19.
This part ActiveWorkbook.Names.Add targetName, targetRefersTo will adds a new named range that refers to the cells on the current sheet
This part namedRange.RefersToRange.Copy Range(targetName) copies the contents of the named range on the Wk1 sheet to the current sheet (remove the line if you don't need it)
Dim RangeName As Variant Try changing the variable type

How to loop through an excel sheet from word

I am struggling to find out how i can loop through all rows in excel from word. What I want to achieve is that if there is something in the WP column in excel then save the active worddocument with that filename. However i cant figure out something simple as getting the last row(might be empty rows in between), i just get error code 424, which according to MSDN does not give me any real hint whats wrong. Any ideas whats wrong?
Public Sub test()
Dim xlapp As Object
Set xlapp = CreateObject("Excel.Application")
myFileName = "Z:\Dokumentstyring\UnderArbeid\PARTSLIST.xlsm"
xlapp.Workbooks.Open myFileName
xlapp.Application.ScreenUpdating = False
xlapp.Visible = False
a = xlapp.sheets("List").Range("A1").Value
b = firstBlankRow(xlapp)
c = getColumn("WP", xlapp)
xlapp.Application.ScreenUpdating = True
xlapp.ActiveWorkbook.Close (True)
xlapp.Quit
Set xlapp = Nothing
End Sub
My function to receive the last row:
Function firstBlankRow(ByRef xlapp) As Long
'returns the row # of the row after the last used row
'Or the first row with no data in it
With xlapp.sheets("List")
'~~> Check if there is any data in the sheet
'If xlapp.WorksheetFunction.CountA(.Cells) <> 0 Then
firstBlankRow = .Range("A" & .Rows.Count).End(Excel.XlDirection.xlUp).Row
'Else
firstBlankRow = 1
'End If
End With
End Function
Here is my function for getting the column number
Public Function getColumn(header As String, ByRef xlapp) As Integer
Dim rng1 As Range
With xlapp.sheets("List")
Set rng1 = .Range(.Cells(1, 1), .Cells(1, Columns.Count)).Find(header, , xlValues, xlWhole)
If Not rng1 Is Nothing Then
getColumn = rng1.Column
Else
MsgBox "Column " & header & " does not exist, Typo??", vbCritical
getColumn = -1
End If
End With
End Function
As per our conversation in the comments, change Dim Rng1 As Range to
Dim Rng1 As Object.
You can find the actual values of XlDirection, Xlvalues, xlwhole enums.
Preferably, it's better to do it like this:
Private Const xlUp as long = -4162
'and so on
Edit1:
Here's an adjusted function that solves your problem (I've tested it on my machine)
Public Function getColumn(header As String, ByRef xlapp) As Long
Dim rng1 As Object
With xlapp.sheets("List")
Set rng1 = .Range(.Cells(1, 1), .Cells(1, .Columns.Count))
If rng1 Is Nothing Then
MsgBox ("ERROR: Range object is empty.")
getColumn = -1
Exit Function
End If
For Each m In rng1
If m = "WP" Then
getColumn = m.Column
Exit Function
End If
Next m
MsgBox "Column " & header & " does not exist, Typo??", vbCritical
getColumn = -1
End With
End Function