我正在使用Excel 2019。
我每周/每月都会收到包含数千到数万行的数据。
我的VBA代码通过只取需要的数据来对这些数据进行排序。
我想从两次约会中排除非工作时间。
我遇到了一个公式,当应用到一个单元格的变量,但我想包括在我的VBA代码。
公式:
=(NETWORKDAYS.INTL([@[DC_CREATION_DATE]],[@[ACTUAL_END_DATE]],""0000000"")-1)*(upper-lower)+IF(NETWORKDAYS.INTL([@[ACTUAL_END_DATE]],[@[ACTUAL_END_DATE]],""0000000""),MEDIAN(MOD([@[ACTUAL_END_DATE]],1),upper,lower),upper)-MEDIAN(NETWORKDAYS.INTL([@[DC_CREATION_DATE]],[@[DC_CREATION_DATE]],""0000000"")*MOD([@[DC_CREATION_DATE]],1),upper,lower)"
我的目标是没有周末(因此使用NetworkDays.Intl自定义将所有设置为使用"0000000"的工作日),并且只设置工作时间(从0800到2300)(上午8:00到晚上11:00),并且从晚上11:01到上午7:59之间的任何时间都不包括在总数中。
以上公式的VBA代码:
Sub RAWDATA_SORT()
Dim Main As Worksheet, Processed As Worksheet
Dim LastRow As Long, col As Long, k As Integer
Dim colName As String, maincolName As String
Dim i As Range
Dim Headers As Range, SearchHeaders As Range
Dim upper As Date, lower As Date, StartDate As Date, EndDate As Date
On Error Resume Next
Set Main = ActiveSheet
Main.Name = "RAW DATA"
Sheets.Add(After:=Sheets("RAW DATA")).Name = "Processed Data"
Set Processed = Sheets("Processed Data")
Main.Activate
Main.ShowAllData
Set Headers = Main.Range("1:1")
LastRow = 0
lower = Format(TimeValue("08:00 AM"), "hh:mm AMPM")
upper = Format(TimeValue("11:00 PM"), "hh:mm AMPM")
Debug.Print (lower)
Debug.Print (upper)
' More Code Here
With Processed
Processed.Activate
Processed.AutoFilterMode = False
Processed.ShowAllData
' More Code Here
LastRow = Main.AutoFilter.Range.Columns(1).SpecialCells(xlCellTypeVisible).Cells.Count
k = 2
For Each i In Range("N2:N" & LastRow)
StartDate = Range("N" & k).Value
EndDate = Range("R" & k).Value
Debug.Print (StartDate)
Debug.Print (EndDate)
Range("U" & k).Value = DateDiff("s", Range("N" & k).Value, Range("R" & k).Value)
Range("V" & k).Value = "=(NETWORKDAYS.INTL([" & StartDate & "],[" & EndDate & "],""0000000"")-1)*([" & upper & "]- [" & lower & "])" _
& "+IF(NETWORKDAYS.INTL([" & EndDate & "],[" & EndDate & "],""0000000""),MEDIAN(MOD([" & EndDate & "],1),[" & upper & "],[" & lower & "]),[" & upper & "])" _
& "-MEDIAN(NETWORKDAYS.INTL([" & StartDate & "],[" & StartDate & "],""0000000"")*MOD([" & StartDate & "],1),[" & upper & "],[" & lower & "])"
k = k + 1
Next i
Range("U:U").NumberFormat = "General"
End With
' Proceeding to End
以下是宏记录器给出的内容:
ActiveCell.FormulaR1C1 = _
"=(NETWORKDAYS.INTL([@[DC_CREATION_DATE]],[@[ACTUAL_END_DATE]],""0000000"")-1)*(upper-lower)" & Chr(10) & "+IF(NETWORKDAYS.INTL([@[ACTUAL_END_DATE]],[@[ACTUAL_END_DATE]],""0000000""),MEDIAN(MOD([@[ACTUAL_END_DATE]],1),upper,lower),upper)" & Chr(10) & "-MEDIAN(NETWORKDAYS.INTL([@[DC_CREATION_DATE]],[@[DC_CREATION_DATE]],""0000000"")*MOD([@[DC_CREATION_DATE]],1),upper,lower)"
我尝试了:
- 将范围("V"& k).值替换为:分子式,分子式R1C1,分子式2,分子式2R1C1
- 用单元格替换区域
- 使用
Application.WorksheetFunction.NetworkDays_Intl
,但我没有足够的经验将整个公式转换为代码。
结果是什么都没有,它没有给出任何错误,但是V列是空的。
或者,是否有更好的解决方案可以在不使用NetworkDays.Intl的情况下排除工作时间(因为没有周末)?
注解掉"错误时继续下一个"后,
运行时错误:1004,应用程序定义或对象定义错误
放在公式所在的行上。
4条答案
按热度按时间cig3rfwq1#
由于发布的公式准确地返回了
DC_CREATION_DATE
和ACTUAL_END_DATE
之间的工作时间,问题似乎是如何使用VBA输入Excel公式。上述公式似乎是从Excel表(即
ListObject
)中获得的,如这些参数所示:而Upper
和Lower
似乎对应于Defined Names
使用标准单元格作为参数的相同公式如下所示:
[@[DC_CREATION_DATE]]
和[@[ACTUAL_END_DATE]]
分别替换为单元格B7
和C7
*这就是行动守则的问题所在
@[DC_CREATION_DATE]
而非[@[DC_CREATION_DATE]]
@[ACTUAL_END_DATE]
而非[@[ACTUAL_END_DATE]]
[
和]
Package 上部和下部我建议在公式的开头添加
DC_CREATION_DATE
和ACTUAL_END_DATE
的验证,如下所示:我建议使用VBA处理excel公式的方法如下:
1.将公式中的参数替换为关键字,在运行过程时,这些关键字将被实际值的
R1C1
引用所替换:...
其中:
#INI
=[@[DC_CREATION_DATE]]
#END
=[@[ACTUAL_END_DATE]]
#LWR
=Lower
#UPR
=Upper
1.定义一个常量以保存公式模板:
...
1.根据需要为参数定义变量:
...
1.将公式模板中的关键字替换为相应的值或R1C1引用:
...
1.输入整个范围的公式,(也可以用结果值替换公式):
...
本程序仅包括工作时间的计算:
z2acfund2#
这里有一个潜在的缺陷:
您正在循环N列中的可见单元格,所以我假设这里应用了一些过滤器,并且隐藏了一些行。
如果第一行(#2)是隐藏的,那么你可以从i=N3开始,但是你的
k
值仍然是2,所以你阅读/写的不是你想要的行。在循环中,
i.EntireRow
将为您提供每个可见行,因此您可以使用(eg)nfs0ujit3#
迟来的回复,不过看看吧。
sd2nnvve4#
我只是简单地使用excel公式完成了这一过程,并且使用我填充的样本数据工作得很好
Sample data and Result
单元格C2中使用的公式
单元格D2中使用的公式
我正在尝试做的是转换工作持续时间,不包括开始和完成日期,将它们乘以15小时。对于开始日期和完成日期中的工作小时数,我正在检查它是否在08:00和23:00之间。以及工作小时数。
在得到总数之后,我再次将它们从总小时数转换为天数、小时数和分钟数,方法是除以15表示天数,除以余数表示小时数和分钟数