[巨集VBA]初心者學習心得02:找到工作表的最後一列lastrow,讓某個sheet工作表sheet activate,找到某個header標頭欄位,鍵值比對快速範例,Range取範圍
找到工作表的最後一列lastrow:
Option Explicit
Sub GetLastRow()
Dim wkbSource As Workbook
Dim strSourceFileToOpen As String
strSourceFileToOpen = ""
'透過dialog視窗取得檔案名稱
strSourceFileToOpen = Application.GetOpenFilename _
(Title:="請選擇 要取得最後一列的excel 的檔案", _
FileFilter:="Excel Files *.xls* (*.xls*),")
If strSourceFileToOpen = "False" Then
MsgBox "選取 要取得最後一列的excel 的檔案失敗!.", vbExclamation, "Sorry!"
Exit Sub
Else
Set wkbSource = Workbooks.Open(strSourceFileToOpen)
wkbSource.Activate
End If
Dim intActiveSheetNoInSourceFile As Integer
intActiveSheetNoInSourceFile = 1
Dim wsSource As Worksheet
Set wsSource = wkbSource.Sheets(intActiveSheetNoInSourceFile)
'關掉畫面上的資料的更新:
Application.ScreenUpdating = False
Dim longLastRowOfSourceFile As Long
longLastRowOfSourceFile = GetLastRowByColumnName(wsSource, "Invoice Date")
Dim longLastRowOfSourceFile1 As Long
longLastRowOfSourceFile1 = GetLastRowByRange(wsSource,FindColumn(wsSource, "Invoice Date") )
'打開畫面上的資料的更新:
Application.ScreenUpdating = True
MsgBox "透過欄位名稱取得最後一列:GetLastRowByColumnName()=" & longLastRowOfSourceFile
MsgBox "透過Range()變數取得最後一列:GetLastRowByRange()=" & longLastRowOfSourceFile1
End Sub
'刪除空白的列
Sub DeleteBlankRows(ws As Worksheet)
Dim longCellLastRow As Long
longCellLastRow = GetLastRowByColumnName(ws, "Invoice Date")
Dim r As Range, rows As Long, i As Long
Set r = ActiveSheet.UsedRange
rows = r.rows.Count
For i = rows To (longCellLastRow + 10) Step (-1)
If WorksheetFunction.CountA(r.rows(i)) = 0 Then r.rows(i).Delete
Next
End Sub
'尋找某個欄位
Function FindColumn(ws As Worksheet, strColumnName As String) As Range
Dim FoundColumn As Range
Set FindColumn = ws.rows("1:1").Find(strColumnName, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)
End Function
'取得最後一列lastrow
Function GetLastRowByRange(ws As Worksheet, rangeColumn As Range) As Long
Dim longLastRow As Long
longLastRow = ws.Cells(rows.Count, rangeColumn.Column).End(xlUp).Row
GetLastRowByRange = longLastRow
End Function
'取得最後一列lastrow
Function GetLastRowByColumnName(ws As Worksheet, strColumnName As String) As Long
Dim longLastRow As Long
longLastRow = ws.Cells(rows.Count, FindColumn(ws, strColumnName).Column).End(xlUp).Row
GetLastRowByColumnName = longLastRow
End Function
完整範例下載:
https://drive.google.com/drive/folders/1nrkNjIdL94WvJX12c_xqfAhtpYV7HNKb?usp=sharing
讓某個sheet工作表activate
Dim sheetName As String
sheetName = "BEFORE"
Worksheets(sheetName).Activate
找某個header標頭欄位:
Option Explicit
Sub Find_header_column()
Dim wkbSource As Workbook
Dim strSourceFileToOpen As String
strSourceFileToOpen = ""
'透過dialog視窗取得檔案名稱
strSourceFileToOpen = Application.GetOpenFilename _
(Title:="請選擇 要被尋找header 的檔案", _
FileFilter:="Excel Files *.xls* (*.xls*),")
If strSourceFileToOpen = "False" Then
MsgBox "選取 要被尋找header!.", vbExclamation, "Sorry!"
Exit Sub
Else
Set wkbSource = Workbooks.Open(strSourceFileToOpen)
wkbSource.Activate
End If
Dim intActiveSheetNoInSourceFile As Integer
intActiveSheetNoInSourceFile = 1
Dim wsSource As Worksheet
Set wsSource = wkbSource.Sheets(intActiveSheetNoInSourceFile)
'關掉畫面上的資料的更新:
Application.ScreenUpdating = False
Dim rangeProductNoColumn As Range
Set rangeProductNoColumn = FindColumn(wsSource, "productno")
'打開畫面上的資料的更新:
Application.ScreenUpdating = True
MsgBox "productno是第" & rangeProductNoColumn.Column & "個欄位"
End Sub
'尋找某個欄位
Function FindColumn(ws As Worksheet, strColumnName As String) As Range
Dim FoundColumn As Range
Set FindColumn = ws.Rows("1:1").Find(strColumnName, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)
End Function
完整範例下載:
https://drive.google.com/drive/folders/10oVSuzkRjtOJ-5ohB9M6-lMttIzfRulb?usp=sharing
鍵值比對快速範例:
內容沒什麼難度以及問題,就是兩個工作表sheet在比對鍵值,放這邊一份copy,方便以後快速複製貼上
'vlook對照:if 處理中的sheet.Line ID == PD 102.Supplier So Shipment No
'PD 102.Cust Name+Sales Name copy回 處理中的sheet.Customer+Sales
'找出處理中的sheet的Line ID欄位
Dim FoundBeforeLineID As Range
Set FoundBeforeLineID = Sheets("BEFORE").Rows("1:1").Find("Line ID", LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)
'找出處理中的sheet的Customer欄位
Dim FoundBeforeCustomer As Range
'找出某某欄位
Set FoundBeforeCustomer = Sheets("BEFORE").Rows("1:1").Find("Customer", LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)
'找出處理中的sheet的Sales欄位
Dim FoundBeforeSales As Range
Set FoundBeforeSales = Sheets("BEFORE").Rows("1:1").Find("Sales", LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)
'找出PD 102的Supplier So Shipment No
'PD 102這個sheet,從RowNumber = 4開始才有資料,因此才會寫Rows("1:4")
Dim FoundPD102Supplier As Range
Set FoundPD102Supplier = Sheets("PD 102").Rows("1:4").Find("Supplier So Shipment No", LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)
'找出PD 102的Cust Name
Dim FoundPD102CustName As Range
Set FoundPD102CustName = Sheets("PD 102").Rows("1:4").Find("Cust Name", LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)
'找出PD 102的Sales Name
Dim FoundPD102SalesName As Range
Set FoundPD102SalesName = Sheets("PD 102").Rows("1:4").Find("Sales Name", LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)
'開始逐筆檢查Line ID
''找出Line ID的最後一筆
lastrow = Sheets("BEFORE").Cells(Rows.Count, FoundBeforeLineID.Column).End(xlUp).Row
For i = 2 To lastrow
Dim lineID As String
lineID = Sheets("BEFORE").Cells(i, FoundBeforeLineID.Column)
'到PD 102工作表跟Supplier So Shipment No欄位比對
lastrowPD102 = Sheets("PD 102").Cells(Rows.Count, FoundPD102Supplier.Column).End(xlUp).Row
Dim custNamePD102 As String
custNamePD102 = "N/A"
Dim salesNamePD102 As String
salesNamePD102 = "N/A"
For ii = 5 To lastrowPD102
Dim compareValue As String
compareValue = Sheets("PD 102").Cells(ii, FoundPD102Supplier.Column)
If lineID = compareValue Then
'順利比對到key值的時候, 就要複製回去處理中的工作表
custNamePD102 = Sheets("PD 102").Cells(ii, FoundPD102CustName.Column)
salesNamePD102 = Sheets("PD 102").Cells(ii, FoundPD102SalesName.Column)
Exit For
End If
Next
Sheets("BEFORE").Cells(i, FoundBeforeCustomer.Column) = custNamePD102
Sheets("BEFORE").Cells(i, FoundBeforeSales.Column) = salesNamePD102
Next
Range取範圍:
'先取出最後一列
Dim FoundBeforeAITPin As Range
Set FoundBeforeAITPin = Sheets("BEFORE").Rows("1:1").Find("AIT P/N", LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)
lastrow = Sheets("BEFORE").Cells(Rows.Count, FoundBeforeAITPin.Column).End(xlUp).Row
'再根據find header的range去設定客製化的range
Dim FoundRate As Range
Set FoundRate = Sheets(sheetName).Rows("1:1").Find("R", LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)
Dim rateRange As Range
Set rateRange = Range(Chr(FoundRate.Column + 64) & "2:" & Chr(FoundRate.Column + 64) & lastrow)
rateRange.Value = InputBox("請輸入匯率")
參考資料:
Range Object - Excel Easy
https://www.excel-easy.com/vba/range-object.html