【问题标题】:Access VBA - Compare an Array to a Dictionary?Access VBA - 将数组与字典进行比较?
【发布时间】:2017-08-09 19:44:01
【问题描述】:

所以我想我可以在 access vba 中设置一个键/值对字典。

这是我想做的这件事的第一部分。

Dim dict as Object 'Declare the Dictionary object
Set dict = CreateObject("Scripting.Dictionary") 'Create the Dictionary

Dim key, val
key = "SomeKey": val = "SomeValue"
'Add item to VBA Dictionary
If Not dict.Exists(key) Then 
    dict.Add key, val
End If 

接下来我需要做的是从列表框中取出所有选定的项目,然后创建一个数组。然后我想遍历该数组,并为数组中的每个项目检查字典中的键。如果匹配,我会将该键的值添加到新数组中。获得新数组后,我将对它进行排序并使其唯一,然后我可以从那里开始使用该“需要值”数组

这有意义吗?

我可以更详细地解释,但我怀疑这是否必要,因为这应该能够以非常普遍的方式应用。

谁能帮我写这个,我将不胜感激!

谢谢


编辑

我已经完成了所有代码来做我想做的事情。我剩下的最后一个问题是,对于子表单控件的源对象,我无法让最终的 SQL 字符串 (Mysql) 作为记录源正确运行。在下面的代码中,我用“'XXX THIS IS WHERE MY ISSUE IS”注释来表示问题出在哪里。下面的代码编译了一些东西: 要选择的字段列表 要加入 From 语句的视图列表,带有左连接 ***(这就是问题) 标准清单 要分组的字段列表

我一直在做一个 debug.print mysql,它在 SSMS 中运行。这是有效的 SQL。但是当有多个连接时,Access 需要所有那些愚蠢的括号。这将使这更加复杂,因为我需要知道我需要将多少括号添加到 sql 连接字符串的 strFrom 部分。这是代码。 strfrom 是我根据当时运行的内容来编译带有尽可能多的 Left Join (s) 的常量 From 字符串的地方:

Private Sub cmdSummary_Click()
    Dim Mysql As String
    Dim strFields As String
    Dim strFrom As String
    Dim strCriteria As String
    Dim strQuery As String
    Dim lbo As ListBox
    Dim itm
    Dim i As Long
    Dim x As Integer
    Dim y As Integer
    Dim selFieldsViewList As String
    Dim selFieldsView() As String
    Dim selFieldsViewU() As String
    Dim FView As String
    Dim selCriteriaViews() As String
    Dim AllViewsJoin() As String


'DETERMINE ANY CRITERIA LISTBOXES WITH SELECTIONS, SO CORRESPONDING VIEW CAN BE ADDED TO FROM/JOIN

    selCriteriaViews = BYOR_ConCriteriaViews()

'Debug.Print "selCriteriaViews:"
'Debug.Print Join(selCriteriaViews, vbCrLf)

    strQuery = "Qry_AnyStandardQuery"

'GATHER SUMMARY FIELDS FOR SELECT AND GROUP BY
    Set lbo = Me.lstFields
    If Me.lstFields.ItemsSelected.Count = 0 Then
        MsgBox "You have not chosen any fields." & vbCrLf & _
        "Attempting to run a report with all fields will be too much!" & vbCrLf & _
        "Please select the summary fields you would like in your report, and run again." & vbCrLf & _
        "Thank you!", vbCritical, "Must Select Fields for Report"
Exit Sub
    Else
        For Each itm In lbo.ItemsSelected
'CREATE , LIST OF FIELDS FOR SELECT AND GROUP BY OF FINAL SQL
            FView = DLookup("sqlView", "tblBYOR_ConFieldViews", "FieldName = '" & lbo.ItemData(itm) & "'")
            strFields = strFields & "[" & FView & "].[" & lbo.ItemData(itm) & "], "
'ADD VALUES TO ARRAY OF SELECTED FIELDS FOR IDENTIFYING VIEWS TO INCLUDE IN FINAL SQL
            FView = DLookup("sqlView", "tblBYOR_ConFieldViews", "FieldName = '" & lbo.ItemData(itm) & "'")
            selFieldsViewList = selFieldsViewList & "," & FView
        Next
        strFields = Left(strFields, Len(strFields) - 2)
        selFieldsView = Split(mid(selFieldsViewList, 2), ",")
    End If

'Debug.Print "selFieldsView:"
'Debug.Print Join(selFieldsView, vbCrLf)
'Debug.Print "selCriteriaViews:"
'Debug.Print Join(selCriteriaViews, vbCrLf)

    AllViewsJoin = Split(Join(selFieldsView, ",") & "," & Join(selCriteriaViews, ","), ",")
'Debug.Print "AllViewsJoin:"
'Debug.Print Join(AllViewsJoin, vbCrLf)

'MAKE VIEW ARRAY UNIQUE, SO WE ONLY JOIN IT ONCE
    selFieldsViewU() = UArray(AllViewsJoin())

'Debug.Print "selFieldsViewU:"
'Debug.Print Join(selFieldsViewU, vbCrLf)

'BUILD THE FROM/JOIN SECTION OF THE SQL
    strFrom = " FROM vw_BYOR_CMCIDs"
'XXX THIS IS WHERE MY ISSUE IS - I HAVE TO DEAL WITH THE JOIN PARENTHESES THAT ACCESS REQUIRES, BECAUSE IT CAN'T TAKE STANDARD SQL
'GRRRR XXX

    For x = LBound(selFieldsViewU) To UBound(selFieldsViewU)
        Select Case selFieldsViewU(x)
            Case "vw_BYOR_ConView1"
                strFrom = strFrom & " Left Join " & selFieldsViewU(x) & " On vw_BYOR_CMCIDs.CID = " & selFieldsViewU(x) & ".CID "
            Case "vw_BYOR_ConView3"
                strFrom = strFrom & " Left Join " & selFieldsViewU(x) & " On vw_BYOR_CMCIDs.CID = " & selFieldsViewU(x) & ".CID "
            Case "vw_BYOR_ConView8"
                strFrom = strFrom & " Left Join " & selFieldsViewU(x) & " On vw_BYOR_CMCIDs.MID = " & selFieldsViewU(x) & ".MID "
            Case Else
                strFrom = strFrom & " Left Join " & selFieldsViewU(x) & " On vw_BYOR_CMCIDs.FKMC = " & selFieldsViewU(x) & ".FKMC "
        End Select
    Next x

'Debug.Print "final strFrom" & vbCrLf & strFrom

'BUILD THE CRITERIA FOR THE SQL, BASED ON ALL LISTBOX FILTER OPTIONS CHOSEN, IF ANY
    strCriteria = "1=1 "
    strCriteria = strCriteria & _
        "BLAH BLAH BLAH"

'CREATE THE FINAL SQL, BY CONTATENTATING THE SELECTED FIELDS, THE FROM/JOIN, THE CRITERIA, AND GROUPING BY SELECTED FIELDS
    Mysql = "SELECT " & vbCrLf & strFields & vbCrLf & strFrom & vbCrLf & " WHERE " & vbCrLf & strCriteria & vbCrLf & " GROUP BY " & vbCrLf & strFields
    Debug.Print Mysql
    CurrentDb.QueryDefs(strQuery).SQL = Mysql
    Me.frmReports_BYOR_SubformQRY.SourceObject = "QUERY." & strQuery
    Me.frmReports_BYOR_SubformQRY.Visible = True
End Sub

如果有人对如何跟踪连接计数有任何想法,请在每次连接后添加开始括号(到 From 字符串,在 From 和主查询之间,然后是结束括号)。只是不确定如何在代码中即时执行此操作。

谢谢。

【问题讨论】:

  • 没有专门的功能。你需要循环你的数组并检查每个项目是否有dict.Exists(...)
  • 谢谢。我想我会一起避免字典。我制作了一个有限键/值对的表,所以我可以遍历数组并对那个表进行 dlookup。我剩下的挑战是当我向数组中添加项目时,只有当项目不在数组中时才添加它,所以我不会被骗。
  • FWIW,您可以使用字典作为您的 final 数组。将您的值作为键,最后将 dict.keys 作为唯一值数组。
  • 这就是我正在研究的内容,但我一直在努力寻找正确的语法来完成我需要做的事情。我正在填充一个数组,现在正在循环遍历它,所以我可以进行 dlookup,找到我需要添加到我的 from/join 语句的视图,然后继续。第一部分是我只想将一个项目添加到数组中,如果它还没有的话。下一部分是,我将数组设置为 Dim selFields() As String,然后循环遍历列表框中的选定项目,并将项目添加到循环中 selFields(i) = lbo.Column(0, i) .我需要该语法仅在它不存在时才这样做,然后循环它
  • 如果您发布一个框架代码,在其中填充您的值数组而没有唯一性约束,则很容易帮助修改它以使用字典以使值是唯一的。

标签: arrays vba dictionary compare ms-access-2010


【解决方案1】:

好的,我搞定了。即使有人否决了我原来的帖子,我发现在 cmets 中说出我的问题很有帮助。我想我会在这里发布我的最终解决方案。这是以下设置: 在 Access 中动态构建您自己的报告表单。
用于过滤的列表框,报告 1个用于选择要进入报表的字段的列表框,以及一个将设置为查询的子表单控件。查询将设置为动态生成的 sql,基于报表表单的列表框选择动态生成。

如果有人想要在此代码中调用的公共函数,即单击运行报告,请发表评论,我会为您发布。

Private Sub cmdSummary_Click()
    Dim Mysql As String
    Dim strFields As String
    Dim strFrom As String
    Dim strCriteria As String
    Dim strQuery As String
    Dim lbo As ListBox
    Dim itm
    Dim i As Long
    Dim x As Integer
    Dim y As Integer
    Dim selFieldsViewList As String
    Dim selFieldsView() As String
    Dim selFieldsViewU() As String
    Dim FView As String
    Dim selCriteriaViews() As String
    Dim AllViewsJoin() As String


'DETERMINE ANY CRITERIA LISTBOXES WITH SELECTIONS, SO CORRESPONDING VIEW CAN BE ADDED TO FROM/JOIN

    selCriteriaViews = BYOR_ConCriteriaViews()

'Debug.Print "selCriteriaViews:"
'Debug.Print Join(selCriteriaViews, vbCrLf)

    strQuery = "Qry_AnyStandardQuery"

'GATHER SUMMARY FIELDS FOR SELECT AND GROUP BY
    Set lbo = Me.lstFields
    If Me.lstFields.ItemsSelected.Count = 0 Then
        MsgBox "You have not chosen any fields." & vbCrLf & _
        "Attempting to run a report with all fields will be too much!" & vbCrLf & _
        "Please select the summary fields you would like in your report, and run again." & vbCrLf & _
        "Thank you!", vbCritical, "Must Select Fields for Report"
Exit Sub
    Else
        For Each itm In lbo.ItemsSelected
'CREATE , LIST OF FIELDS FOR SELECT AND GROUP BY OF FINAL SQL
            FView = DLookup("sqlView", "tblBYOR_ConFieldViews", "FieldName = '" & lbo.ItemData(itm) & "'")
            strFields = strFields & "[" & FView & "].[" & lbo.ItemData(itm) & "], "
'ADD VALUES TO ARRAY OF SELECTED FIELDS FOR IDENTIFYING VIEWS TO INCLUDE IN FINAL SQL
            FView = DLookup("sqlView", "tblBYOR_ConFieldViews", "FieldName = '" & lbo.ItemData(itm) & "'")
            selFieldsViewList = selFieldsViewList & "," & FView
        Next
        strFields = Left(strFields, Len(strFields) - 2)
        selFieldsView = Split(mid(selFieldsViewList, 2), ",")
    End If

'Debug.Print "selFieldsView:"
'Debug.Print Join(selFieldsView, vbCrLf)
'Debug.Print "selCriteriaViews:"
'Debug.Print Join(selCriteriaViews, vbCrLf)

    AllViewsJoin = Split(Join(selFieldsView, ",") & "," & Join(selCriteriaViews, ","), ",")
'Debug.Print "AllViewsJoin:"
'Debug.Print Join(AllViewsJoin, vbCrLf)

'MAKE VIEW ARRAY UNIQUE, SO WE ONLY JOIN IT ONCE
    selFieldsViewU() = UArray(AllViewsJoin())

'Debug.Print "selFieldsViewU:"
'Debug.Print Join(selFieldsViewU, vbCrLf)


 'COUNT HOW MANY JOINS, SO THE RIGHT AMOUNT OF OPENING PARENTHESES WILL BE ADDED TO THE FROM CLAUSE
 JoinCount = UBound(selFieldsViewU) + 1
'BUILD THE FROM/JOIN SECTION OF THE SQL
     strFrom = " FROM " & String(JoinCount, "(") & "vw_BYOR_CMCIDs "

    For x = LBound(selFieldsViewU) To UBound(selFieldsViewU)
        Select Case selFieldsViewU(x)
            Case "vw_BYOR_ConView1"
                strFrom = strFrom & " Left Join " & selFieldsViewU(x) & " On vw_BYOR_CMCIDs.CID = " & selFieldsViewU(x) & ".CID) "
            Case "vw_BYOR_ConView3"
                strFrom = strFrom & " Left Join " & selFieldsViewU(x) & " On vw_BYOR_CMCIDs.CID = " & selFieldsViewU(x) & ".CID) "
            Case "vw_BYOR_ConView8"
                strFrom = strFrom & " Left Join " & selFieldsViewU(x) & " On vw_BYOR_CMCIDs.MID = " & selFieldsViewU(x) & ".MID) "
            Case Else
                strFrom = strFrom & " Left Join " & selFieldsViewU(x) & " On vw_BYOR_CMCIDs.FKMC = " & selFieldsViewU(x) & ".FKMC) "
        End Select
    Next x

'Debug.Print "final strFrom" & vbCrLf & strFrom

'BUILD THE CRITERIA FOR THE SQL, BASED ON ALL LISTBOX FILTER OPTIONS CHOSEN, IF ANY
    strCriteria = "1=1 "
    strCriteria = strCriteria & _
        "BLAH BLAH BLAH"

'CREATE THE FINAL SQL, BY CONTATENTATING THE SELECTED FIELDS, THE FROM/JOIN, THE CRITERIA, AND GROUPING BY SELECTED FIELDS
    Mysql = "SELECT " & vbCrLf & strFields & vbCrLf & strFrom & vbCrLf & " WHERE " & vbCrLf & strCriteria & vbCrLf & " GROUP BY " & vbCrLf & strFields
    Debug.Print Mysql
    CurrentDb.QueryDefs(strQuery).SQL = Mysql
    Me.frmReports_BYOR_SubformQRY.SourceObject = "QUERY." & strQuery
    Me.frmReports_BYOR_SubformQRY.Visible = True
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-22
    • 2013-12-21
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多