use*_*103 5 macos excel vba dictionary
I\xe2\x80\x99m 尝试获取包含宏的 Excel 2011 32 位(适用于 Mac)电子表格。问题是这个宏在 PC 上运行良好,但在 Mac 上却不行。我尝试导入 Tim Hall\xe2\x80\x99s Dictionary.cls,但它仍然不起作用。KeyValuePair.cls 也是如此。
\n\n\n\n\n错误:运行时错误 \xe2\x80\x99429\xe2\x80\x99\n ActiveX 组件无法\xe2\x80\x99t 创建对象
\n
我\xe2\x80\x99m 不是程序员,所以问题可能是我,不知道要改变什么才能让事情正常工作。对于那些知道自己在做什么的人来说,这\xe2\x80\x99 可能非常容易。谁能花几分钟查看这些文件并告诉我需要更改哪些部分才能使其运行?[我认为它确实有效\xe2\x80\xa6]
\n\nFWIW,我尝试在两个地方用 \xe2\x80\x9cNew.Dictionary\xe2\x80\x9d 替换 \xe2\x80\x9cScripting.Dictionary\xe2\x80\x9d (见下文),但这并没有 \xe2\ x80\x99t 让它工作。
\n\nSet dAttributes = CreateObject("New.Dictionary")\n\nSet dValues = CreateObject("New.Dictionary\xe2\x80\x9d)\nRun Code Online (Sandbox Code Playgroud)\n\n随机化数据文件:
\n\nOption Explicit\nSub GenerateResults()\n\nDim LO As ListObject\nDim LO2 As ListObject\nDim LR As ListRow\nDim ws As Worksheet\nDim cCount As Integer\nDim gCount As Integer\nDim dAttributes As Object\nDim dValues As Object\nDim dKey As Variant\nDim c As Range\nDim v As Variant\nDim i As Integer\nDim InsertCount As Integer\n\nSet LO = ActiveSheet.ListObjects("Data")\nIf LO Is Nothing Then MsgBox "Please select the table and re-run": Exit Sub\nWith Application\n.EnableEvents = False\n.DisplayAlerts = False\n.ScreenUpdating = False\nEnd With\nLO.AutoFilter.ShowAllData\n\nSet ws = ActiveWorkbook.Sheets.Add\nws.Range("A1:C1").Value = Array("Candidate", "Attribute", "Value")\nws.ListObjects.Add xlSrcRange, Range("A1:C1"), , xlYes\nSet LO2 = ws.Range("A1").ListObject\n\nSet dAttributes = CreateObject(\xe2\x80\x9cNew.Dictionary")\nFor Each c In LO.ListColumns("Attribute").DataBodyRange.Cells\nIf Not dAttributes.Exists(c.Value) Then dAttributes(c.Value) = c.Value\nNext c\n\nFor Each dKey In dAttributes.Keys\nLO.Range.AutoFilter Field:=LO.ListColumns("Attribute").Index, Criteria1:=dKey\ngCount = Evaluate("SUM(--(FREQUENCY(IF(" & LO.Name & "[Attribute]=""" & dKey & """,MATCH(" & LO.Name & "[Value]," & LO.Name & "[Value],0)),ROW(" & LO.Name & "[Value])-ROW(" & LO.Name & "[[#Headers],[Value]]))>0))")\ncCount = Evaluate("SUM(--(FREQUENCY(IF(" & LO.Name & "[Attribute]=""" & dKey & """,MATCH(" & LO.Name & "[Candidate]," & LO.Name & "[Candidate],0)),ROW(" & LO.Name & "[Candidate])-ROW(" & LO.Name & "[[#Headers],[Candidate]]))>0))")\nv = GenerateSplit(cCount, gCount)\nSet dValues = CreateObject(\xe2\x80\x9cNew.Dictionary")\n\nFor Each c In LO.ListColumns("Value").DataBodyRange.SpecialCells(xlCellTypeVisible)\n If Not dValues.Exists(c.Value) Then dValues(c.Value) = c.Value\nNext c\n\nInsertCount = 0\ni = 1\nFor Each c In LO.ListColumns("Candidate").DataBodyRange.SpecialCells(xlCellTypeVisible)\nTryAgain:\nIf i <= v(InsertCount, 2) Then\n Set LR = LO2.ListRows.Add\n LR.Range.Value = Array(c.Value, dKey, dValues.Items()(InsertCount))\n i = i + 1\nElse\n i = 1\n InsertCount = InsertCount + 1\n GoTo TryAgain\nEnd If\nNext c\n\nNext dKey\nLO.AutoFilter.ShowAllData\nLO.Range.Worksheet.Select\n\nWith Application\n.EnableEvents = True\n.DisplayAlerts = True\n.ScreenUpdating = True\nEnd With\n\nEnd Sub\nRun Code Online (Sandbox Code Playgroud)\n\n编辑代码
\n\nOption Explicit\nSub GenerateResults()\n\nDim LO As ListObject\nDim LO2 As ListObject\nDim LR As ListRow\nDim ws As Worksheet\nDim cCount As Integer\nDim gCount As Integer\nDim dAttributes As Object\nDim dValues As Object\nDim dKey As Variant\nDim c As Range\nDim v As Variant\nDim i As Integer\nDim InsertCount As Integer\n\n#If Mac Then\nSet dAttributes = New Dictionary\nSet dValues = New Dictionary\n#Else\nSet dAttributes = CreateObject("Scripting.Dictionary")\nSet dValues = CreateObject("Scripting.Dictionary")\n#End If\n\nSet LO = ActiveSheet.ListObjects("Data")\nIf LO Is Nothing Then MsgBox "Please select the table and re-run": Exit Sub\nWith Application\n.EnableEvents = False\n.DisplayAlerts = False\n.ScreenUpdating = False\nEnd With\nLO.AutoFilter.ShowAllData\n\nSet ws = ActiveWorkbook.Sheets.Add\nws.Range("A1:C1").value = Array("Candidate", "Attribute", "Value")\nws.ListObjects.Add xlSrcRange, Range("A1:C1"), , xlYes\nSet LO2 = ws.Range("A1").ListObject\n\n\' Set dAttributes = CreateObject("New Dictionary")\nFor Each c In LO.ListColumns("Attribute").DataBodyRange.Cells\nIf Not dAttributes.Exists(c.value) Then dAttributes(c.value) = c.value\nNext c\n\nFor Each dKey In dAttributes.Keys\nLO.Range.AutoFilter Field:=LO.ListColumns("Attribute").Index, Criteria1:=dKey\ngCount = Evaluate("SUM(--(FREQUENCY(IF(" & LO.Name & "[Attribute]=""" & dKey & """,MATCH(" & LO.Name & "[Value]," & LO.Name & "[Value],0)),ROW(" & LO.Name & "[Value])-ROW(" & LO.Name & "[[#Headers],[Value]]))>0))")\ncCount = Evaluate("SUM(--(FREQUENCY(IF(" & LO.Name & "[Attribute]=""" & dKey & """,MATCH(" & LO.Name & "[Candidate]," & LO.Name & "[Candidate],0)),ROW(" & LO.Name & "[Candidate])-ROW(" & LO.Name & "[[#Headers],[Candidate]]))>0))")\nv = GenerateSplit(cCount, gCount)\n\' Set dValues = CreateObject("Scripting.Dictionary")\n\nFor Each c In LO.ListColumns("Value").DataBodyRange.SpecialCells(xlCellTypeVisible)\n If Not dValues.Exists(c.value) Then dValues(c.value) = c.value\nNext c\n\nInsertCount = 0\ni = 1\nFor Each c In LO.ListColumns("Candidate").DataBodyRange.SpecialCells(xlCellTypeVisible)\nTryAgain:\nIf i <= v(InsertCount, 2) Then\n Set LR = LO2.ListRows.Add\n LR.Range.value = Array(c.value, dKey, dValues.Items()(InsertCount))\n i = i + 1\nElse\n i = 1\n InsertCount = InsertCount + 1\n GoTo TryAgain\nEnd If\nNext c\n\nNext dKey\nLO.AutoFilter.ShowAllData\nLO.Range.Worksheet.Select\n\nWith Application\n.EnableEvents = True\n.DisplayAlerts = True\n.ScreenUpdating = True\nEnd With\n\nEnd Sub\nRun Code Online (Sandbox Code Playgroud)\n
New.Dictionary不是有效的类名,在 PC 上也会失败。通常使用早期绑定的构造是:
Set obj = New Dictionary\nRun Code Online (Sandbox Code Playgroud)\n\n或者使用后期绑定:
\n\nSet obj = CreateObject("Scripting.Dictionary")\nRun Code Online (Sandbox Code Playgroud)\n\n然而,Mac OS 没有脚本运行时库,因此您无法使用这些东西——字典、FileSystemObject 等。
\n\n您需要使用 Collection 或其他数据类型来代替 Dictionary 类型,或者您可以借用其他答案并实现自定义的类似字典的 Class。
\n\n\n\n\n我尝试导入 Tim Hall\xe2\x80\x99s Dictionary.cls,但它仍然不起作用。KeyValuePair.cls 也是如此。
\n
我怀疑您根本不知道您还需要使用条件编译方法来分配DictionaryMac 操作系统上的类,以及Scripting.DictionaryWindows 操作系统上的类。
删除这两行:
\n\nSet dAttributes = CreateObject("New.Dictionary")\nSet dValues = CreateObject("New.Dictionary")\nRun Code Online (Sandbox Code Playgroud)\n\n正如我上面所描述的,即使在 Windows 中它们也会失败。同样,如果您想在 Win 和 Mac 环境中使用此代码,则必须Scripting.Dictionary采取一些额外的预防措施以避免错误才能使用。
您将需要使用编译器指令来实现条件编译来识别操作系统。对于以前做过的人来说这并不太复杂,但大多数初学者甚至不知道他们可以使用它,更不用说如何使用它了。
\n\n在伪代码中,基本上你正在这样做:
\n\nIf the operating system is Mac, then:\n Do this\nElseIf the operating system is Win, then:\n Do that instead\nEnd If\nRun Code Online (Sandbox Code Playgroud)\n\n假设您已将实现字典副本的其他答案中的代码KeyValuePair.cls 复制 到纯文本文件中,并将这两个模块导入到项目的 VBE 中。Dictionary.cls
#IF Mac Then\n Set dAttributes = New Dictionary\n Set dValues = New Dictionary\n#Else\n Set dAttributes = CreateObject("Scripting.Dictionary")\n Set dValues = CreateObject("Scripting.Dictionary")\n#End If\nRun Code Online (Sandbox Code Playgroud)\n\n我会将这段代码放在该行的上方:
\n\nSet LO = ActiveSheet.ListObjects("Data")\nRun Code Online (Sandbox Code Playgroud)\n\n实际上,只要您将该代码放在调用 或之前的任何位置,那么将其放在哪里都没有关系。dAttributesdValues
这应该适用于两种操作系统,因为它们Dictionary.cls模仿了Scripting.Dictionary\ 的方法。
注意:最好将这些对象分配分组,而不是在整个过程中随意地散布它们,特别是当您使用条件编译时,因为它将更易于人类阅读并且更容易维护。
\n| 归档时间: |
|
| 查看次数: |
19745 次 |
| 最近记录: |