excel - Excel VBA:查找日期范围表中的日期行
问题描述
嗨,提前感谢您的帮助。提取单元格中包含日期的每日文件。我需要使用日期在表格中查找它属于哪一周,该表格在两列中有开始日期和结束日期。一旦我知道日期所在的行,我需要在后续列中提取更多数据。交叉引用表的格式如下:从源中提取的日期变量(分配给字符串和日期变量)需要与 col 的 A 和 B 进行比较,以找出它适合的行,然后提取财政年度(Col A) 以及简短描述 (col F)
调整和重命名的目标文件如下所示
解决方案
在代码中处理了几个问题后,@PGTester 提供的函数效果很好:
1) 声明:每种类型的声明都在一行中。这在 VBA 中不起作用,因为只有最后一个变量被声明为预期的,而所有之前的变量都被声明为变体。(即,DIM adate、bdate、cdate 作为日期)在此示例中,只有 cdate 是实际日期。在更正声明之前,将日期传递给函数会导致不匹配。(@Domenic 指出了这一点)
2) 日期格式:虽然源文件和交叉引用文件中的所有日期在调用函数之前都被格式化为“yyyy-mmm-dd”,但错误 13,类型不匹配仍然阻止代码继续前进。将源文件(在代码中完成)和交叉引用表(在访问之前手动)上的格式更改为“md-yyyy”解决了这个问题,以下代码按预期工作。
3) 将函数调用指向 vlookup 和 rnglookup 的交叉引用文件是通过为所需页面构建和设置变量来完成的。这在需要时简化了选择。
Set variables for next steps
'
Set CRef = Workbooks.Open(refFILE)
Set shtJOB = CRef.Sheets("JobCross")
Set shtDATE = CRef.Sheets("fcalendar")
sht.Activate
Set rngJOBS = Range("i2:i" & lastRow)
Set rngJBGRP = shtJOB.Range("A1:b16")
Set rng = shtDATE.Range("A2:f210")
具有这两个功能的完整代码如下:
Sub CleanDaily_Labour()
'
' CleanDaily_Labour Macro
' RMDC Payroll Resarch (MU) Report prep
'
' Note the separate declarations for each variable
'
Dim myPath As String, fName As String, refFILE As String, job As String, _
JobGR As String, DateST As String, WKDay As String, PDWK As String
Dim CRef As Workbook, wkb As Workbook
Dim shtDATE As Worksheet, shtJOB As Worksheet, sht As Worksheet
Dim aDate As Date, fYR As Date
Dim fYear As Variant
Dim rng As Range, rngJOBS As Range, rngJBGRP As Range
Dim SC As Long, lastRow As Long, PD As Long, WK As Long
' Application.ScreenUpdating = False
myPath = Application.ActiveWorkbook.Path
'
' Get the file date and assign to variables
'
Range("D3").Select
**Selection.NumberFormat = "m-d-yyyy"**
aDate = Range("D3").Value
DateST = WorksheetFunction.Text(aDate, "YYYYMMDD")
WKDay = WorksheetFunction.Text(aDate, "DDD")
Selection.Copy
Range("D7").Select
ActiveSheet.Paste
'
' Rename and save the active workbook by date
' set wkb to new workbook name and assign calendar cross ref
'
fName = myPath & "\Daily_Labour_" _
& DateST & ".xlsx"
ActiveWorkbook.SaveAs fName, 51
Set wkb = Workbooks.Open(fName)
Set sht = wkb.Sheets("Sheet1")
refFILE = myPath & "\Cross_Ref_fCalendar.xlsx"
'
' Remove extra header info
'
Rows("1:5").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
'
' Insert Column to the left of Column D
'
Columns("E:G").Insert Shift:=xlToRight, _
CopyOrigin:=xlFormatFromRightOrBelow
'
' Update Headers that will be kept / used
'
Range("A1").Value = "FYear"
Range("E1").Value = "PD_WK"
Range("J1").Value = "JOB_GRP"
Range("F1").Value = "WKDay"
Range("G1").Value = "PD"
Range("H1").Value = "WK"
'
Rows("1:1").Select
With Selection
.HorizontalAlignment = xlCenter
End With
'
' Remove extra columns
'
Sheets("Sheet1").Range("K:K,M:P,R:AY").EntireColumn.Delete
'
' Get the last row and fill known columns
'
lastRow = Cells(Rows.Count, 1).End(xlUp).row
Range("d2:d" & lastRow).Value = aDate
Range("d2:d" & lastRow).NumberFormat = "m-d-yyyy"
Range("f2:f" & lastRow).Value = WKDay
'
' Set variables for next steps
'
Set CRef = Workbooks.Open(refFILE)
Set shtJOB = CRef.Sheets("JobCross")
Set shtDATE = CRef.Sheets("fcalendar")
sht.Activate
Set rngJOBS = Range("i2:i" & lastRow)
Set rngJBGRP = shtJOB.Range("A1:b16")
Set rng = shtDATE.Range("A2:f210")
'
' Loop through jobs in column i match job in shtJOB
' put matching group in row j (Use Function vLookupVBA)
'
For Each jRow In rngJOBS
jRow.Select
job = ActiveCell.Value
JobGR = VLookupVBA(job, rngJBGRP, Null)
ActiveCell.Offset(0, 1).Value = JobGR
'end for
Next jRow
'
'Save Progress during testing:
'
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs fName, 51
'
' Fill in date parameters from Cross Ref file for Business date
' Use function rngLOOKUP to update variables then set ranges to the variables
' May be more efficient to get row number from cross ref table instead - later.
'
shtDATE.Activate '(does not seem to affect)
'
fYear = rngLOOKUP(aDate, rng, 3)
PDWK = rngLOOKUP(aDate, rng, 6)
PD = rngLOOKUP(aDate, rng, 4)
WK = rngLOOKUP(aDate, rng, 5)
'
' Fill the columns with the variables (can likely bypass the variables and put on 1 line)- later
'
sht.Activate
Range("A2:A" & lastRow).Value = fYear
Range("E2:E" & lastRow).Value = PDWK
Range("G2:G" & lastRow).Value = PD
Range("H2:H" & lastRow).Value = WK
'
' Close reference file
'
Application.DisplayAlerts = False
CRef.Close False
'
' Cleanup, save and close workbooks
'
Application.DisplayAlerts = False
wkb.SaveAs fName, 51
'
' SQL call: Load to existing datbase (GDrive), use same format as Transactions
' ?? Get sales by day? vs maintain PDWK - Future
'
Application.DisplayAlerts = True
Application.ScreenUpdating = True
' wkb.Close.false
End Sub
Private Function VLookupVBA(what As Variant, lookupRng As Range, defaultValue As Variant) As Variant
Dim rv As Variant: rv = Application.VLookup(what, lookupRng, lookupRng.Columns.Count, False)
If IsError(rv) Then
VLookupVBA = "NULL"
Else
VLookupVBA = rv
End If
End Function
Public Sub UsageExample()
MsgBox VLookupVBA("ValueToFind", ThisWorkbook.Sheets("ReferenceSheet").Range("A:D"), "Not found!")
End Sub
Function rngLOOKUP(chkDate As Date, rngf As Range, theColumn As Long) As Variant
Dim acell As Range
'
For Each acell In rngf.Columns(1).Cells
If acell.Value <= chkDate And acell.Offset(0, 1).Value >= chkDate Then
rngLOOKUP = acell.Offset(0, theColumn - 1).Value
Exit Function
End If
Next acell
rngLOOKUP = "#Nothing"
End Function
推荐阅读
- javascript - 如何配置 TypeScript 以隐藏窗口中的所有全局变量,但访问窗口本身?
- angular - 从子组件获取值到父组件
- elasticsearch - 如何忽略 kibana 查询中突出显示的字段?
- c++ - 即使使用正确的键,QMap 也会返回空值(键具有相同的地址:不可能不正确吗?)
- google-cloud-platform - 如何在 Google Cloud SQL 2nd Gen 上跳过从属复制错误
- android - 对返回 when 语句感到困惑
- java - 如何将 WAR 文件部署到 Wildfly?
- bash - 无法从 azure 管道 Git 推送到远程分支(非主分支)
- python-3.x - Python3 - 从文本文件中删除一行时出现问题
- python - 有没有办法将python中的多行字符串解析为列表列表