我的目标是计算来自呼叫管理器的每个呼叫的电话费用。该脚本适用于小型表(<1k),但会卡在实际数据上。
我的通话表有16万行。q_get_call结果为6列。该脚本每次都能正常工作,直到7431行为止。我在较小的表上尝试过,它也完成了他的工作。如果我不使用DoEvents函数,Access将不再响应,但是Script也仅在30分钟后直到第8000行左右运行。
常见问题:vba中是否有一些重要的事情,例如在每次循环后将变量设置回0,以处理此类数据大小?
我已经将查询减少为所需的那4列。选择案例陈述可能会更好吗?还是有比我的insertSQL方法更好的方法来将成本更新到call_table中?
如果我在几分钟后暂停脚本,它将卡在DoEvents()函数中。
Set Datenbank = CurrentDb
Set rs_calls = Datenbank.OpenRecordset("q_get_called", dbOpenDynaset)
'Loop through all call-data to calculate cost
Do While Not rs_calls.EOF
callID = rs_calls!globalCallID_CallId
internal = rs_calls!IfInternal
inside = rs_calls!FromInside
If inside = 0 Or internal = -1 Then 'cost is Zero if call coming from outside or is internal
cost = 0
Else 'else proceed calculation
callingNr = rs_calls!callingPartyNumber
calledNr = rs_calls!finalCalledPartyNumber
duration = rs_calls!duration
If Left(calledNr, 3) Like "0??" Then 'domestic
multiplier = 1
ElseIf Left(calledNr, 3) Like "00?" Then multiplier = 5 'national
ElseIf Left(calledNr, 3) Like "000" Then multiplier = 10 'international
Else: multiplier = 0
End If
'Select Case Left(calledNr, 3) 'Maybe Select case is smarter?
' Case "0??"
' multiplier = 1
' Case "00?"
' multiplier = 5
' Case "000"
' multiplier = 10
' Case Else
' multiplier = 0
'End Select
cost = (duration / 60) * multiplier
End If
insertSQL = "UPDATE tbl_cdr SET cost = " & cost & " WHERE globalCallID_callID = " & callID
Datenbank.Execute (insertSQL) 'set cost column
rs_calls.MoveNext
subForm = DoEvents() 'pass control to OS
Loop
因此,由于解决方案现在可以使用更新查询直接在访问中完成所有操作。
UPDATE tbl_cdr SET tbl_cdr.cost = IIf(Left([tbl_cdr].[calledNumber],3)="000",
([tbl_cdr].[duration]/60)*10, IIf(Left([tbl_cdr].[calledNumber],2)="00",
([tbl_cdr].[duration]/60)*5, IIf (Left([tbl_cdr].[calledNumber],1)="0",
[tbl_cdr].[duration]/60,0)));
不到1分钟即可解决。我的计算将变得更加复杂。就像也用分隔呼叫callingNumber
,并根据它们使用不同的Multiplier常数。
编辑:我现在实现了更多的逻辑,并且努力在一个SQL Update语句中完成所有操作
是否可以像这样输入更新语句的子查询:
UPDATE tbl_cdr SET [tbl_cdr].[cost]=
IIf([tbl_cdr].[fromInside]=-1,
IIf(Left([tbl_cdr].[fncpn],3)="000",
([tbl_cdr].[duration]/60)*
(SELECT international FROM [tbl_cc] WHERE ccc=Left(cpn,4);),
IIf(Left([tbl_cdr].[fncpn],2)="00",
([tbl_cdr].[duration]/60)*
(SELECT national FROM [tbl_cost] WHERE ccc=Left(cpn,4);),
IIf(Left([tbl_cdr].[fncpn],1)="0",
([tbl_cdr].[duration]/60)*
(SELECT domestic FROM [tbl_cost] WHERE ccc=Left(cpn,4);),
0)
)
)
,0)
;`
错误日志:“操作必须使用可更新的查询”
-我确实拥有该文件夹的所有权限
-链接的表包含主键
还是将其IIf-clauses
与SQL混合的正确方法?
由于解决方案可能需要对每个不同的查询 callingCountry
像这样:
UPDATE tbl_cdr AS cdr SET cdr.cost = cdr.duration* (SELECT cc.international FROM tbl_costConstant AS cc WHERE cc.callingCountryCode = 1760) WHERE cdr.finalCalledPartyNumber Like "000%" AND cdr.callingPartyNumber Like "1760%";
不过,这似乎是一个很大的解决方法。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句