Run VBA Excel script on an Excel document from an Access subroutine - excel

I have a section of code to find the bottom right cell, that runs in excel, and I want to be able to run it through an Access subroutine, which will return the cell coordinates (Ex.: J17). However I'm not that familiar with Access and am unsure of how to translate the code.
Sub FindLast_Message()
MsgBox FindLast(3)
End Sub
Function FindLast(lRowColCell As Long, _
Optional sSheet As String, _
Optional sRange As String)
'Find the last row, column, or cell using the Range.Find method
'lRowColCell: 1=Row, 2=Col, 3=Cell
Dim lRow As Long
Dim lCol As Long
Dim wsFind As Worksheet
Dim rFind As Range
'Default to ActiveSheet if none specified
On Error GoTo ErrExit
If sSheet = "" Then
Set wsFind = ActiveSheet
Else
Set wsFind = Worksheets(sSheet)
End If
'Default to all cells if range no specified
If sRange = "" Then
Set rFind = wsFind.Cells
Else
Set rFind = wsFind.Range(sRange)
End If
On Error GoTo 0
Select Case lRowColCell
Case 1 'Find last row
On Error Resume Next
FindLast = rFind.Find(What:="*", _
After:=rFind.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
Case 2 'Find last column
On Error Resume Next
FindLast = rFind.Find(What:="*", _
After:=rFind.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
Case 3 'Find last cell by finding last row & col
On Error Resume Next
lRow = rFind.Find(What:="*", _
After:=rFind.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
On Error Resume Next
lCol = rFind.Find(What:="*", _
After:=rFind.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
On Error Resume Next
FindLast = wsFind.Cells(lRow, lCol).Address(False, False)
'If lRow or lCol = 0 then entire sheet is blank, return "A1"
If Err.Number > 0 Then
FindLast = rFind.Cells(1).Address(False, False)
Err.Clear
End If
On Error GoTo 0
End Select
Exit Function
ErrExit:
MsgBox "Error setting the worksheet or range."
End Function
Below is the section of Access code where I need to coordinate this with. The 'J72' should be the bottom right cell coordinate as returned by the previous code.
Sub Format_Excel_Workbook(workbook_path As String, worksheet_name As String, myRows As Integer, myColumns As Integer)
'==============================================================================
Dim objExcelApp As Object
Dim xlWbk As Object
'==============================================================================
Dim x, y As String
x = "B2"
y = "J72"
Z = x & ":" & y
'==============================================================================
Set objExcelApp = New Excel.Application
objExcelApp.Workbooks.Open (workbook_path)
objExcelApp.Worksheets("t_DATA").Columns.AutoFit
objExcelApp.Worksheets("t_DATA").Range(x).Select
objExcelApp.ActiveWindow.FreezePanes = True
objExcelApp.Worksheets("t_DATA").Range(Z).HorizontalAlignment = xlCenter
objExcelApp.Worksheets("t_DATA").Range(Z).VerticalAlignment = xlTop
objExcelApp.ActiveWorkbook.Close (True)
Set objExcelApp = Nothing
'==============================================================================
End Sub

The easiest way is probably to change the parameters of your FindLast() function to objects instead of strings:
Function FindLast(lRowColCell As Long, _
Optional sSheet As Excel.Worksheet, _
Optional sRange As Excel.Range)
From Excel, you could call this function like this:
FindLast(3, , FindLast(3, , ThisWorkbook.Sheets(1).Range("A3:E7")))
In the function you have to change those parts where the parameters sSheet and sRange are used: Simply use the provided objects instead of creating them from the strings.
With the function changed this way you can easily transport it to other host applications like Access, because the caller of the function defines the objects on which the function should operate, not the function itself.
From Access you could invoke the function like this:
FindLast(3, , objExcelApp.Worksheets("t_DATA").Range(Z))

Related

What is correct syntax for using R1C1 and clearing formats of a Range to end of sheet?

I am making a macro that Optimizes the sheet by deleting unused ranges that create very large file sizes. It does this by finding the last used row (column), selecting a range from that last used row (column) to the very bottom-right) of the sheet, and clearing formats and deleting those cells, to delete the unused range that is taking up space.
E.g. if last used row is 50, select range A50 to Bottom right of sheet (aka XFD104873, clear those formats and delete range
I have been able to do this with rows, but not with columns. In the below code, I get a syntax error (shown as 'SYNTAX ERROR' below) when case 2 runs, and I can't for the life of me figure out why.
I need to use R1C1 notation but for some reason the range(cells(#,#)) aren't picking it up properly.
I think it has to do with the second part in which I do range(cells(#,#)).End(xlDown).end(Toright)
Let me know if i can provide any additional information!
Nick
'Option Explicit
Sub Optimize()
'Call OptimizeSheet(1, "HR_Data")
Call OptimizeSheet(2, "DomesticAsset_Data")
'Call OptimizeSheet(3, "InternationalAsset_Data")
End Sub
Sub OptimizeSheet(ByVal choice As Long, ByVal sht As String)
' 1 = Rows
' 2 = Columns
' 3 = Both
If WorksheetExists(sht) = False Then
MsgBox "Worksheet doesn't exist, check macro code"
Exit Sub
End If
'Workbook
Dim wb As Workbook
'Last Row and Column Variables
Dim lr As Long
Dim lc As Long
'File Size variables
Dim aFileSize As Long
Dim bFileSize As Long
Dim chngFileSize As Long
Set wb = Application.ActiveWorkbook
On Error GoTo errHandler
'Get file size before optimizing
aFileSize = FileLen(Application.ActiveWorkbook.FullName)
Select Case choice
'Rows
Case 1:
lr = Worksheets(sht).Cells.Find(What:="*", _
After:=Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
With Worksheets(sht).Range("A" & lr, Range("A" & lr).End(xlDown).End(xlToRight))
.ClearFormats
.Delete
End With
'Columns
Case 2:
lc = Worksheets(sht).Cells.Find(What:="*", _
After:=Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
SYNTAX ERROR HERE
With Worksheets(sht).Range(Cells(1, lc), RangeCells(1, lc).End(xlDown).End(xlToRight))
.ClearFormats
.Delete
End With
'Both
Case 3:
lr = Worksheets(sht).Cells.Find(What:="*", _
After:=Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
With Worksheets(sht).Range("A" & lr, Range("A" & lr).End(xlDown).End(xlToRight))
.ClearFormats
.Delete
End With
'chnge
lc = Worksheets(sht).Cells.Find(What:="*", _
After:=Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
With Worksheets(sht).Range(Cells(1, lc).Address(), Range(Cells(1, lc).Address()).End(xlDown).End(xlToRight))
.ClearFormats
.Delete
End With
Case Else:
MsgBox "Wrong Choice, check macro code"
End Select
Application.ThisWorkbook.Save
bFileSize = FileLen(Application.ActiveWorkbook.FullName)
If aFileSize + bFileSize = 0 Then
MsgBox "error in filesize"
End If
chngFileSize = bFileSize - aFileSize
If chngFileSize = 0 Then
MsgBox (sht & " already optimized")
Else
MsgBox ("Done. " & (chngFileSize / 1000) & "MB Saved")
End If
Exit Sub
errHandler:
MsgBox "error on line" & Erl
End Sub
Function WorksheetExists(shtName As String, Optional wb As Workbook) As
Boolean
Dim sht As Worksheet
If wb Is Nothing Then Set wb = ThisWorkbook
On Error Resume Next
Set sht = wb.Sheets(shtName)
On Error GoTo 0
WorksheetExists = Not sht Is Nothing
End Function
To delete columns:
With Worksheets(sht)
.Range(.Cells(1, lc + 1), _
.Cells(1, lc +1 ).End(xlToRight)).EntireColumn.Delete
End With

Range Selection Method Dilemma

I need more experienced persons advice on some situation which I am facing. I have a test sample data in the following table.
hello good day today
hello good day today
hello good day today
hello good day today
hello good day today
hello good day today
hello good day today
today
today
I have used 4 ways to determine range as per following code and also the last cell by FIND method.
Sub test()
Dim ws As Worksheet
Dim myRange As Range
Dim myRange1 As Range
Dim myRange2 As Range
Dim rLastCell As Range
Set ws = ThisWorkbook.ActiveSheet
With ws
Set myRange = .Range(.Cells(1, 1), .Range("A1").SpecialCells(xlCellTypeLastCell))
Debug.Print ws.Name, myRange.Address
'set range with used area
Set myRange1 = ws.UsedRange
Debug.Print ws.Name, myRange1.Address
'set range with currentegion
Set myRange2 = .Range("A1").CurrentRegion
Debug.Print ws.Name, myRange2.Address
' finding lastcell and then set range
Set rLastCell = ActiveSheet.Cells.Find(What:="*", After:=.Cells(1, 1), LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False)
Debug.Print rLastCell.Address
End With
End Sub
Results of Debug.Print are
Book1 $A$1:$D$11
Book1 $A$1:$D$11
Book1 $A$1:$D$6
$D$11
My specific query is that by UsedRange, SpecialCells(xlCellTypeLastCell) and FIND method I get the same results. Though use of these or other approaches depend on the situation at hand but considering this particular data situation, Is over-riding preference for a particular method is warranted.
EDIT:
Based on comments of #VBasic2008 and an excellent article referred by # QHarr , I am inclined to adopt for range determination in general situations following methodology. I would like to find Last Row and Last Column of the range utilizing the Last function suggested in Ron de Bruin Aricle . Range will be set based on Anchor Cell and Last Row and Last Column Values.Code followed by me as follows.
Sub Range_Detrmine()
Dim ws As Worksheet
Dim LastRow As Long
Dim LastCol As Long
Dim rng As Range
Dim Frng As Range
Set ws = ThisWorkbook.ActiveSheet
With ws
' Use all cells on the sheet
Set rng = .Cells
' Find the last row
LastRow = Last(1, rng)
LastCol = Last(2, rng)
Set Frng = .Range(.Cells(1, 1), .Cells(LastRow, LastCol))
Debug.Print LastRow & ":"; LastCol
Debug.Print ws.Name, Frng.Address
End With
End Sub
Function Last(choice As Long, rng As Range)
'Ron de Bruin, 5 May 2008
' 1 = last row
' 2 = last column
' 3 = last cell
Dim lrw As Long
Dim lcol As Long
Select Case choice
Case 1:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
Case 2:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
Case 3:
On Error Resume Next
lrw = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
On Error Resume Next
lcol = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
On Error Resume Next
Last = rng.Parent.Cells(lrw, lcol).Address(False, False)
If Err.Number > 0 Then
Last = rng.Cells(1).Address(False, False)
Err.Clear
End If
On Error GoTo 0
End Select
End Function
I tested the above code for some example situations as per snapshots appended. I tested the correctness of range determined before deleting formatted row and after deleting the formatted row.Also in case of filter applied it is giving correct range even though filter check-marks are visible in Header Row in Column H
Debug.Print LastRow & ":"; LastCol
Debug.Print ws.Name, Frng.Address
Results before and after range modification are :
17: 8
Sheet1 $A$1:$H$17
14: 7
Sheet2 $A$1:$G$14
I would like to know if there are some caveats to this approach.

Creating a form to submit a csv file with content

I havethe following problem:
To be able to deploy multiple devices, I have edited some VBA code I found here and there and I'm lost at the moment... Because I'm not a coder, and I don't understand exactly what the code does, I can't figure out the solution.
The problem is: when I add 1 device, the .csv file is cluttered with data:
HOSTNAMEHQ,COUNTRYCRE,HARDWARECRE,MAC,UUID,DESCRIPTION,PLATFORM
LPAB00000013293,,,28:F1:0E:30:81:C1,,STOCK,
#N/A,,,#N/A,,STOCK,
#N/A,,,#N/A,,STOCK,
#N/A,,,#N/A,,STOCK,
#N/A,,,#N/A,,STOCK,
#N/A,,,#N/A,,STOCK,
(etc)
When I add 2 or more devices, the .csv file is OK:
HOSTNAMEHQ,COUNTRYCRE,HARDWARECRE,MAC,UUID,DESCRIPTION,PLATFORM
LPAB00000013293,,,28:F1:0E:30:81:C1,,STOCK,
LPAB00000013293,,,28:F1:0E:30:81:C1,,STOCK,
The code I'm using is:
Sub Button_Click()
Call SaveWorksheetsAsCsv
End Sub
Sub SaveWorksheetsAsCsv()
On Error Resume Next
Dim i As Long
Errorknop = vbCritical + vbOKOnly
ThisWorkbook.Sheets("Export").Visible = xlSheetVisible
ThisWorkbook.Sheets("Export").Activate
Range("A1").Select
Selection.End(xlDown).Select
LaRo = ActiveCell.Row
Range("A1").Select
Range("A2").Select
Selection.End(xlDown).Select
LR = ActiveCell.Row
LC = Last(4, ActiveSheet.Cells)
LCR = LC & LR
Range("B1:" & LCR).Copy
ThisWorkbook.Sheets("Export").Visible = xlSheetHidden
ThisWorkbook.Sheets("Export_2").Visible = xlSheetVisible
ThisWorkbook.Sheets("Export_2").Activate
Range("A1").Select
Range("A1").PasteSpecial Paste:=xlPasteValues
Dim LValue As Date
LValue = Now
Dim SaveToDirectory As String
Dim CurrentWorkbook As String
Dim CurrentFormat As Long
Dim strbody As String
Dim SigString As String
Dim Signature As String
CurrentWorkbook = ThisWorkbook.FullName
CurrentFormat = ThisWorkbook.FileFormat
SaveToDirectory = "D:\Testmap\Formulieren\"
Worksheets("Export_2").SaveAs Filename:=SaveToDirectory & Day(LValue) & Month(LValue) & Year(LValue) & Hour(LValue) & Minute(LValue) & Second(LValue) & "_1IMPORT_TEMPLATE_NN_AD_SCCM_HP", FileFormat:=xlCSV
ThisWorkbook.Saved = True
Application.Quit
End Sub
Function Last(choice As Integer, rng As Range)
' 1 = last row
' 2 = last column (R1C1)
' 3 = last cell
' 4 = last column (A1)
Dim lrw As Long
Dim lcol As Integer
Select Case choice
Case 1:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
Case 2:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
Case 3:
On Error Resume Next
lrw = rng.Find(What:="*", _
After:=rng.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
lcol = rng.Find(What:="*", _
After:=rng.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
Last = Cells(lrw, lcol).Address(False, False)
If Err.Number > 0 Then
Last = rng.Cells(1).Address(False, False)
Err.Clear
End If
On Error GoTo 0
Case 4:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
Last = R1C1converter("R1C" & Last, 1)
For i = 1 To Len(Last)
s = Mid(Last, i, 1)
If Not s Like "#" Then s1 = s1 & s
Next i
Last = s1
End Select
End Function
Function GetBoiler(ByVal sFile As String) As String
'Dick Kusleika
Dim fso As Object
Dim ts As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2)
GetBoiler = ts.readall
ts.Close
End Function
Function R1C1converter(Address As String, Optional R1C1_output As Integer, Optional RefCell As Range) As String
'Converts input address to either A1 or R1C1 style reference relative to RefCell
'If R1C1_output is xlR1C1, then result is R1C1 style reference.
'If R1C1_output is xlA1 (or missing), then return A1 style reference.
'If RefCell is missing, then the address is relative to the active cell
'If there is an error in conversion, the function returns the input Address string
Dim x As Variant
If RefCell Is Nothing Then Set RefCell = ActiveCell
If R1C1_output = xlR1C1 Then
x = Application.ConvertFormula(Address, xlA2, xlR1C1, , RefCell) 'Convert A2 to R1C1
Else
x = Application.ConvertFormula(Address, xlR1C1, xlA2, , RefCell) 'Convert R1C1 to A2
End If
If IsError(x) Then
R1C1converter = Address
Else
'If input address is A1 reference and A1 is requested output, then Application.ConvertFormula
'surrounds the address in single quotes.
If Right(x, 1) = "'" Then
R1C1converter = Mid(x, 2, Len(x) - 2)
Else
x = Application.Substitute(x, "$", "")
R1C1converter = x
End If
End If
End Function
For a coder this might be completely logical or even a big mess, but I really hope someone can give me the solution so the script runs, get's the information for the cells, and then stops when it finds an empty cell. At that moment, write the .csv file and close.
I found the solution using a step-by-step method with F8. Finding the last row was where the error was. Now I'm using:
Cells(Rows.Count, "A").End(xlUp).Row

VBA Identify numbers within a range

I am sure this is a simple one but cant seem to find anything explicit out on the WWW.
I need my code to identify any numbers between 1 and 9 within a column for it to throw the error back for that range, I can only get it working with one number at present.
Public Sub ErrorCheck()
Dim FindString As String
Dim Rng As Range
FindString = ""
If VBA.Trim(FindString) <> "" Then
With Sheets("Scoring").Range("S:S")
Set Rng = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
MsgBox "Error", True
Else
End If
End With
End If
End Sub
Thanks for your help!
You can execute your code iteratively for all the values you want. Example:
Public Sub ErrorCheck()
Dim FindString As String
Dim Rng As Range
Dim startVal As Integer, endVal As Integer
startVal = 1
endVal = 9
For i = startVal To endVal
FindString = CStr(i)
With Sheets("Scoring").Range("S:S")
Set Rng = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
MsgBox "Error", True
Exit For
Else
End If
End With
Next i
End Sub

Using the Find Function in VBA

1
2
3
4
.
.
So I have a sequence of numbers running from 1-20. I have the number "1" on top selected and I would like to search the entire column and find the number "9". The code works when I don't name the range "rng"; it finds the number and selects. But the code stops working when I name the range of number. What's wrong with the range function? could it be that if I define Dim rng as Range that when I later define the "Set rng=" I cannot have the ".Select" or ".Copy" extension on the end?
Sub macro2()
Dim rng As Range
Set rng = Range(ActiveCell, ActiveCell.End(xlDown)).Select
rng.Find(10).Select
End Sub
Also, If I want to sum the entire column from 1-20, on the last cell below the number "20" should I use the following code? because the application object doesn't seem to do it. Thank you!
rng.End(xlDown).Offset(1, 0).Select
Application.WorksheetFunction.Sum (rng.Value)
To look for 10 in the active column you could try this (which ends up selecting the first 10 - although Select in vba isn't normally needed other than taken the user to location at code end)
test that the found range exists (ie you can find 10 before proceeding)
you should also use xlWhole to avoid matching 100 if the current default for [lookAt] is xlPart
using search [After] as Cells(1, ActiveCell.Column , and [Search Direction] as xlNext finds the first value looking down.
code
Sub QuickFind()
Dim rng1 As Range
Set rng1 = ActiveCell.EntireColumn.Find(10, Cells(1, ActiveCell.Column), xlFormulas, xlWhole, , xlNext)
If Not rng1 Is Nothing Then
Application.Goto rng1
Else
MsgBox "10 not found"
End If
End Sub
Part 2
Sub Other()
Dim rng1 As Range
Set rng1 = Range(Cells(1, ActiveCell.Column), Cells(Rows.Count, ActiveCell.Column).End(xlUp))
rng1.Cells(rng1.Cells.Count).Offset(1, 0) = Application.WorksheetFunction.Sum(rng1.Value)
End Sub
Try this, I hope this will help u to find the specific row no as well as column name too. In code you can use
strRw = FindColumn(Sheet name, "Value which need to be found", True, "Cell Name",Row number)
sourceCOL = colname(FindColumn(Shee Name, "Value which need to be found", False, , 4))
Below is main function of find
Public Function FindColumn(colnocountWS As Worksheet, srcstr As String, Optional rowflag As Boolean, Optional bycol As String, Optional strw As Integer, Optional stcol As Integer) As Integer
Dim srcrng As Range 'range of search text
Dim srcAddr As String 'address of search text
Dim stcolnm As String
colnocountWS.Activate
If stcol <> 0 Then stcolnm = colname(stcol)
If stcol = 0 Then stcolnm = "A"
If strw = 0 Then strw = 1
colnocountWS.Range(stcolnm & strw).Select
If ActiveSheet.Range(stcolnm & strw) = srcstr Then
ActiveSheet.Range(stcolnm & strw).Select
FindColumn = 1
Else
If bycol = "" Then
Set srcrng = colnocountWS.Cells.Find(Trim(srcstr), after:=ActiveCell, LookIn:=xlValues _
, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Else
Set srcrng = colnocountWS.Cells.Find(Trim(srcstr), after:=ActiveCell, LookIn:=xlValues _
, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
End If
'ByPart
If srcrng Is Nothing Then
If bycol = "" Then
Set srcrng = colnocountWS.Cells.Find(Trim(srcstr), after:=ActiveCell, LookIn:=xlValues _
, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Else
Set srcrng = colnocountWS.Cells.Find(Trim(srcstr), after:=ActiveCell, LookIn:=xlValues _
, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
End If
End If
If srcrng Is Nothing Then
FindColumn = 0
Exit Function
Else
srcAddr = srcrng.Address
colnocountWS.Range(srcAddr).Select
FindColumn = ActiveCell.Column
If rowflag = True Then FindColumn = ActiveCell.Row
End If
End If
End Function
'this function find column name
Public Function colname(iFinalCol1 As Integer) As String
Dim colnm As String
On Error GoTo gg
If Mid(Cells(1, iFinalCol1).Address, 3, 1) = "$" Then
colnm = Mid(Cells(1, iFinalCol1).Address, 2, 1)
Else
colnm = Mid(Cells(1, iFinalCol1).Address, 2, 2)
End If
gg: colname = colnm
End Function

Resources