我正尝试在Access 2010的VBA中编写一个循环,其中该循环通过一个表(表:“ SunstarAccountsInWebir_SarahTest”)进行查找并评估许多条件,并取决于条件-然后可能循环通过另一个表(“ 1042s_FinalOutput_7”)来查看其ID是否匹配。如果匹配,则将“ Test”插入到字段中;如果不匹配,则应将值行(从第一个循环中“ SunstarAccountsInWebir_SarahTest”中导出)导出到excel文件中。
我的问题是我的代码正在导出表“ SunstarAccountsInWebir_SarahTest”的整个表,我只希望它在循环中导出与i的值相对应的行。如何修改我的代码来做到这一点?
Public Sub EditFinalOutput2()
'set loop variables
Dim i As Long
Dim qs As DAO.Recordset
Dim ss As DAO.Recordset
Dim strSQL As String
Dim external_nmad_id As String
Dim IRSfileFormatKey As String
'Function GetID(external_nmad_id As String, IRSfileFormatKey As String)
'open reference set
Set db = CurrentDb
Set qs = db.OpenRecordset("SunstarAccountsInWebir_SarahTest")
Set ss = db.OpenRecordset("1042s_FinalOutput_7")
'set loop for whole recordset(this is the original location, will try putting it within the If, ElseIf loop)
'For i = 0 To qs.RecordCount - 1
With qs.Fields
For i = 0 To qs.RecordCount - 1
If (IsNull(!nmad_address_1) Or (!nmad_address_1 = !nmad_city) Or (!nmad_address_1 = !Webir_Country) And IsNull(!nmad_address_2) Or (!nmad_address_2 = !nmad_city) Or (!nmad_address_2 = !Webir_Country) And IsNull(!nmad_address_3) Or (!nmad_address_3 = !nmad_city) Or (!nmad_address_3 = !Webir_Country)) Then
MsgBox "This was an invalid address"
Else:
With ss.Fields
For j = 0 To ss.RecordCount - 1
If (qs.Fields("external_nmad_id") = Right(ss.Fields("IRSfileFormatKey"), 10)) Then
ss.Edit
ss.Fields("box13_Address") = "Test"
ss.Update
Else: DoCmd.TransferSpreadsheet acExport, 10, "SunstarAccountsInWebir_SarahTest", "\\DTCHYB-MNMH001\C_WBGCTS_Users\U658984\My Documents\pre processor\PreProcessor7\ToBeReviewed\AddressesNotActiveThisYear.xlsx", False
End If
ss.MoveNext
Next j
End With
End If
qs.MoveNext
Next i
End With
'close reference set
qs.Close
Set qs = Nothing
ss.Close
Set ss = Nothing
结束子
答案 0 :(得分:1)
这最终是最接近的。我需要切换到“ Do While”循环,而不是第二个整数循环。这样的代码如下:Public Sub EditFinalOutput2()
'set variables
Dim i As Long
Dim qs As DAO.Recordset
Dim ss As DAO.Recordset
Dim strSQL As String
Dim external_nmad_id As String
Dim IRSfileFormatKey As String
Dim mytestwrite As String
mytestwrite = "No"
'open reference set
Set db = CurrentDb
Set qs = db.OpenRecordset("SunstarAccountsInWebir_SarahTest")
Set ss = db.OpenRecordset("1042s_FinalOutput_7")
With qs.Fields
For i = 0 To qs.RecordCount - 1
If (IsNull(!nmad_address_1) Or (!nmad_address_1 = !nmad_city) Or
(!nmad_address_1 = !Webir_Country) And IsNull(!nmad_address_2) Or (!nmad_address_2 =
!nmad_city) Or (!nmad_address_2 = !Webir_Country) And IsNull(!nmad_address_3) Or
(!nmad_address_3 = !nmad_city) Or (!nmad_address_3 = !Webir_Country)) Then
DoCmd.RunSQL "INSERT INTO Addresses_ToBeReviewed SELECT
SunstarAccountsInWebir_SarahTest.* FROM SunstarAccountsInWebir_SarahTest WHERE
(((SunstarAccountsInWebir_SarahTest.external_nmad_id)='" & qs!external_nmad_id &
"'));"
Else:
Set ss = db.OpenRecordset("1042s_FinalOutput_7")
With ss.Fields
'if not invalid address, loop through second (final output) table to find
matching ID's
If ss.EOF = False Then
ss.MoveFirst
Do
Dim mykey As String
mykey = Right(ss!IRSfileFormatKey, 10)
Debug.Print mykey
If qs.Fields("external_nmad_id") = mykey Then
ss.Edit
ss.Fields("box13c_Address") = qs.Fields("nmad_address_1") &
qs.Fields("nmad_address_2") & qs.Fields("nmad_address_3")
ss.Update
mytestwrite = "Yes"
End If
ss.MoveNext
'if the valid address doesn't match to final output table, add to list of
addresses not matched
Loop Until ss.EOF
If mytestwrite = "No" Then
DoCmd.SetWarnings False
DoCmd.RunSQL "INSERT INTO Addresses_NotUsed SELECT
SunstarAccountsInWebir_SarahTest.* FROM SunstarAccountsInWebir_SarahTest WHERE
(((SunstarAccountsInWebir_SarahTest.external_nmad_id)='" & qs!external_nmad_id &
"'));"
DoCmd.SetWarnings True
End If
End If
End With
End If
qs.MoveNext
Next i
End With
'close reference set
qs.Close
Set qs = Nothing
ss.Close
Set ss = Nothing
End Sub
答案 1 :(得分:0)
创建这样的查询,然后执行它,并将dim rst返回为Recordset 注意:我已将AND-s更改为OR-s,因为这正是我想您要的...
Select qs.*
From
(Select *
From SunstarAccountsInWebir_SarahTest
Where Not
(
(IsNull(nmad_address_1)
Or (nmad_address_1 = nmad_city)
Or (nmad_address_1 = Webir_Country)
OR IsNull(nmad_address_2)
Or (nmad_address_2 = nmad_city)
Or (nmad_address_2 = Webir_Country)
OR IsNull(nmad_address_3)
Or (nmad_address_3 = nmad_city)
Or (nmad_address_3 = Webir_Country)
)
) as qs
Left Join
(Select *
,Right(ss.Fields("IRSfileFormatKey"), 10) as ssKey
From 1042s_FinalOutput_7
) as ss
On qs.external_nmad_id = ss.ssKey
Where ssKey is NULL
' Copy field names to the first row of the worksheet
fldCount = rst.Fields.Count
For iCol = 1 To fldCount
xlWs.Cells(1, iCol).Value = rst.Fields(iCol - 1).Name
Next
' Copy the recordset to the worksheet, starting in cell A2
xlWs.Cells(2, 1).CopyFromRecordset rst
'Note: CopyFromRecordset will fail if the recordset
'contains an OLE object field or array data such
'as hierarchical recordsets
答案 2 :(得分:0)
好的,根据您设定的目标,您的方法中有一些错误。
以下是我根据开头的段落来了解您的目标的方法:
遍历表
TableA
中的每个记录。如果记录符合 某些复杂的条件,请搜索第二个表TableB
以查看是否存在TableB
中的记录包含来自此记录中的匹配ID值TableA
。如果存在匹配项,则更新TableB
中的字段,否则,将记录从TableA
导出到Excel。
我将描述您提供的代码如何处理数据,然后解释如何解决此问题。
首先,正如@ScottHoltzman所暗示的那样,您在代码中使用的DoCmd.TransferSpreadsheet
语句当然会将整个表传输到Excel,因为这就是您要执行的操作。第三个参数指定要导出的数据,并为其指定了完整的表名,因此将导出完整的表。
第二,我认为您误会了代码中两个RecordSet的循环实际上是如何工作的。您的代码正在执行以下操作:
qs
中的记录。如果不符合条件,请移至下一个qs
记录并重复步骤1。qs
中的记录确实符合条件,请对照ss
中的该记录评估qs
中的记录。ss
并移至下一个ss
记录,转到步骤2,请记住qs
仍指向同一记录并且没有移动。 / li>
ss
记录,转到步骤2,再次记住qs
仍指向同一记录并且具有没动。ss
中的所有记录均已通过步骤2、3和4处理后,移至下一个qs
记录并转到步骤1 我希望您的代码可以多次将表导出到Excel。
我还希望您的代码在开始处理移至步骤2的第二条qs
记录后会出错,因为在处理了第一个{{1 }}符合您条件的记录,qs
RecordSet将指向EOF,并且您没有任何代码可将指针移回到ss
中的第一条记录。
无论如何,由于您有复杂的标准来确定是否导出记录,因此建议向ss
添加一个名为TableA
的单个True / False字段。现在,在代码的开头,您将为ToExport
中的所有记录设置ToExport
= False
。然后,您的代码将工作以评估TableA
中的每条记录,以确定是否应导出该记录。如果需要,则将TableA
更新为ToExport
。遍历整个表后,仅需要导出的记录将被标记为True
。现在,您仅将ToExport = True
记录导出到Excel,从而获得所需的结果。
这里有一些代码应以有效的方式实现此目标。此代码尝试使用原始来源中的表和条件。利用内置的RecordSet循环和EOF检查,它还将True
块和With
循环替换为更有用的For
循环。
Do
我希望这可以帮助您更好地实现自己的目标。