如何填充表中不符合特定条件的数据?

huangapple go评论100阅读模式
英文:

How to populate data that don't match specific criteria in table?

问题

I have 2 tabs, 1 Summary tab and the other 1 is Data tab. The summary tab contains a table with specific customer numbers(as shown in the summary table below).

我有两个选项卡,一个是汇总选项卡,另一个是数据选项卡。汇总选项卡包含一个具有特定客户号码的表格(如下所示)。

I'm trying to achieve the same set of data and columns that are listed in the summary table but for the rest of the customer numbers that do not exist in the summary table and insert them in a listbox.

我试图实现与汇总表中列出的相同的数据和列,但对于汇总表中不存在的其余客户号码,并将它们插入到一个列表框中。

Can anyone help me please with that?

有人能帮助我吗?

Thank you!

谢谢!

My Summary Table:

我的汇总表格:

Customer Number Customer Name aged debt Count of invoices Value
55850 ABC 1-30 2 2516
55850 ABC 30-60 1 52635
55850 ABC 60-90 1 102754
55850 ABC 90-120 1 152873
55850 ABC 120-180 1 202992
32336 DEF 30-60 2 253111
32336 DEF 60-90 2 303230
30131 GHI 1-30 1 353349
30131 GHI 30-60 2 403468
30131 GHI 60-120 2 453587
13914 JKL 1-30 2 503706
13914 JKL 30-60 2 553825
13914 JKL 60-90 2 603944
13914 JKL 90-120 1 654063

我的汇总表格:

客户号码 客户名称 逾期债务 发票数 价值
55850 ABC 1-30 2 2516
55850 ABC 30-60 1 52635
55850 ABC 60-90 1 102754
55850 ABC 90-120 1 152873
55850 ABC 120-180 1 202992
32336 DEF 30-60 2 253111
32336 DEF 60-90 2 303230
30131 GHI 1-30 1 353349
30131 GHI 30-60 2 403468
30131 GHI 60-120 2 453587
13914 JKL 1-30 2 503706
13914 JKL 30-60 2 553825
13914 JKL 60-90 2 603944
13914 JKL 90-120 1 654063

My Data source

我的数据源

Customer Number Customer Name Invoice Number Invoice Date Flag aged debt Value area
55850 ABC 121 01/01/2022 Yes 1-30 1258 ES
55850 ABC 122 02/01/2022 Yes 1-30 1258 WE
55850 ABC 123 03/01/2022 Yes 30-60 52635 NO
55850 ABC 124 04/01/2022 No 60-90 102754 SO
55850 ABC 125 05/01/2022 Yes 90-120 152873 ES
55850 ABC 126 06/01/2022 Yes 120-180 202992 WE
32336 DEF 127 07/01/2022 No 30-60 126555.5 NO
32336 DEF 128 08/01/2022 Yes 30-60 126555.5 SO
32336 DEF 129 09/01/2022 Yes 60-90 151615 ES
32336 DEF 130 10/01/2022 No 60-90 151615 WE
30131 GHI 131 11/01/2022 Yes 1-30 353349 NO
英文:

I have 2 tabs, 1 Summary tab and the other 1 is Data tab. The summary tab contains a table with specific customer numbers(as shown in the summary table below).

I'm trying to achieve the same set of data and columns that are listed in the summary table but for the rest of the customer numbers that do not exist in the summary table and insert them in a listbox.

can anyone help me please with that?

Thank you!

My Summary Table:

Customer Number Customer Name aged debt Count of invoices Value
55850 ABC 1-30 2 2516
55850 ABC 30-60 1 52635
55850 ABC 60-90 1 102754
55850 ABC 90-120 1 152873
55850 ABC 120-180 1 202992
32336 DEF 30-60 2 253111
32336 DEF 60-90 2 303230
30131 GHI 1-30 1 353349
30131 GHI 30-60 2 403468
30131 GHI 60-120 2 453587
13914 JKL 1-30 2 503706
13914 JKL 30-60 2 553825
13914 JKL 60-90 2 603944
13914 JKL 90-120 1 654063

My Data source

Customer Number Customer Name Invoice Number Invoice Date Flag aged debt Value area
55850 ABC 121 01/01/2022 Yes 1-30 1258 ES
55850 ABC 122 02/01/2022 Yes 1-30 1258 WE
55850 ABC 123 03/01/2022 Yes 30-60 52635 NO
55850 ABC 124 04/01/2022 No 60-90 102754 SO
55850 ABC 125 05/01/2022 Yes 90-120 152873 ES
55850 ABC 126 06/01/2022 Yes 120-180 202992 WE
32336 DEF 127 07/01/2022 No 30-60 126555.5 NO
32336 DEF 128 08/01/2022 Yes 30-60 126555.5 SO
32336 DEF 129 09/01/2022 Yes 60-90 151615 ES
32336 DEF 130 10/01/2022 No 60-90 151615 WE
30131 GHI 131 11/01/2022 Yes 1-30 353349 NO
30131 GHI 132 12/01/2022 Yes 30-60 201734 SO
30131 GHI 133 13/01/2022 No 30-60 201734 ES
30131 GHI 134 14/01/2022 No 60-120 226793.5 WE
30131 GHI 135 15/01/2022 Yes 60-120 226793.5 NO
13914 JKL 136 16/01/2022 Yes 1-30 251853 SO
13914 JKL 137 17/01/2022 Yes 1-30 251853 ES
13914 JKL 138 18/01/2022 Yes 30-60 276912.5 WE
13914 JKL 139 19/01/2022 Yes 30-60 276912.5 NO
13914 JKL 140 20/01/2022 Yes 60-90 301972 SO
13914 JKL 141 21/01/2022 Yes 60-90 301972 ES
13914 JKL 142 22/01/2022 Yes 90-120 654063 WE
13900 LMN 143 23/01/2022 No 1-30 120000 NO
13900 LMN 144 24/01/2022 Yes 30-60 180000 SO
13900 LMN 145 25/01/2022 Yes 60-90 50000 ES
13900 LMN 146 26/01/2022 No 90-120 60000 WE
13900 LMN 147 27/01/2022 Yes 120-180 70000 NO
13901 OOO 148 28/01/2022 Yes 30-60 3000 SO
13901 OOO 149 29/01/2022 No 60-90 40000 ES
13901 OOO 150 30/01/2022 No 90-120 50000 WE
13901 OOO 151 31/01/2022 No 120-180 60000 NO
13902 OOX 152 01/02/2022 No 30-60 10000 SO
13902 OOX 153 02/02/2022 No 60-90 20000 ES
13902 OOX 154 03/02/2022 Yes 90-120 30000 WE
13902 OOX 155 04/02/2022 Yes 120-180 40000 NO
  1. Option Explicit
  2. Sub test()
  3. Dim conn, rs As Object, sq As String, Accounts As String
  4. Set conn = CreateObject("ADODB.Connection")
  5. With conn
  6. .Provider = "Microsoft.ACE.OLEDB.12.0"
  7. .ConnectionString = "Data Source=" &
  8. ThisWorkbook.FullName & ";" & _
  9. "Extended Properties=""Excel 12.0
  10. Xml;HDR=Yes;IMEX=1"";"
  11. .Open
  12. End With
  13. sq = "SELECT T1.[Customer Number],T1.
  14. [Customer Name],T1.[Aged Debt] " & _
  15. "COUNT(T1.[Invoice Number]) as [count of Invoices] " & _
  16. "sum(T1.[Value]) as [values] " & _
  17. "FROM[Data$] T1 " & _
  18. "WHERE T1.[Customer Number] Not In (" & Getcust(Accounts) & ") " & _
  19. "GROUP BY T1.[Customer Number],T1.[Customer Name],T1.[Aged Debt]"
  20. Set rs = conn.Execute(sq)
  21. If Not rs.EOF Then
  22. With Me.listbox1
  23. .Value = ""
  24. .Column = rs.GetRows
  25. .ColumnCount = rs.Fields.Count
  26. .ColumnHeads = False
  27. .ColumnWidths = "90,90,50,50,180"
  28. End With
  29. End If
  30. rs.Close
  31. conn.Close
  32. Set rs = npthing
  33. Set conn = Nothing
  34. End Sub
  35. Public Function Getcust(Accounts As String) As String
  36. Dim dU1 As Object, cU1 As Variant, iU1 As Long, i As Integer
  37. Set dU1 = CreateObject("Scripting.Dictionary")
  38. cU1 = Sheets("Summary").ListObjects(1).ListColumns("Customer
  39. Number").DataBodyRange
  40. For iU1 = 1 To UBound(cU1, 1)
  41. dU1(cU1(iU1, 1)) = 1
  42. Next iU1
  43. Accounts = "'"
  44. For i = 0 To dU1.Count - 1
  45. Accounts = Accounts & dU1.Keys()(i) & "','"
  46. Next
  47. Accounts = Left(Accounts, Len(Accounts) - 5)
  48. Getcust = Accounts
  49. End Function

答案1

得分: 0

Here are the translated parts of your code:

  1. Write two Connection Only Power queries to read your Summary Data and your Datasource
  2. Then Merge those queries using a LeftAnti join to get only the rows in data source that do not exist in the summary.
  3. You can then use Transform, Group By to get the details you need for your summary e.g.
  4. let
  5. Source = Table.NestedJoin(DataSource, {"Customer Number"}, Summary, {"Customer Number"}, "Summary", JoinKind.LeftAnti),
  6. #"Grouped Rows" = Table.Group(Source, {"Customer Number", "Customer Name", "aged debt"}, {{"Count of invoices", each Table.RowCount(_), Int64.Type}, {"Value", each List.Sum([Value]), type nullable number}})
  7. in
  8. #"Grouped Rows"

Please note that I've left the code in its original format and haven't translated the actual Power Query code.

英文:

Write two Connection Only Power queries to read your Summary Data and your Datasource
Then Merge those queries using a LeftAnti join to get only the rows in data source that do not exist in the summary.
You can then use Transform, Group By to get the details you need for your summary e.g.

  1. let
  2. Source = Table.NestedJoin(DataSource, {"Customer Number"}, Summary, {"ustomer Number"}, "Summary", JoinKind.LeftAnti),
  3. #"Grouped Rows" = Table.Group(Source, {"Customer Number", "Customer Name", "aged debt"}, {{"Count of invoices", each Table.RowCount(_), Int64.Type}, {"Value", each List.Sum([Value]), type nullable number}})
  4. in
  5. #"Grouped Rows"

答案2

得分: 0

请使用标准的方式。您必须从真正存在的地方(工作表)设置lisObjects(表格)。活动工作表必须包含一个名为 "ListBox1" 的 ActiveX 列表框:

  1. Sub LoadListBoxWithNotExistingCustomNo()
  2. Dim tbl1 As ListObject, tbl2 As ListObject, arrT1, arrT2, arrUnique, mtch, arrIt, arFin
  3. Dim i As Long, j As Long, dict As New Scripting.Dictionary
  4. Dim listB As msforms.listbox
  5. '在此处使用两个涉及的表格真正存在的工作表:
  6. Set tbl1 = ActiveSheet.ListObjects("T1.") '第一个表格对象
  7. Set tbl2 = ActiveSheet.ListObjects("T2.") '第二个表格对象
  8. arrT1 = tbl1.DataBodyRange.Value2 '将它们的内容放入数组以加快处理速度
  9. arrT2 = tbl2.DataBodyRange.Value2
  10. For i = 1 To UBound(arrT1)
  11. dict(arrT1(i, 1)) = vbNullString '提取唯一的客户号码
  12. Next i
  13. arrUnique = dict.keys '将字典键放入数组中
  14. dict.RemoveAll '清空字典以重新使用它...
  15. '在字典中加载必要的数据:
  16. For i = 1 To UBound(arrT2)
  17. mtch = Application.Match(arrT2(i, 1), arrUnique, True)
  18. If Not IsNumeric(mtch) Then
  19. If Not dict.Exists(arrT2(i, 1) & "|" & arrT2(i, 6)) Then
  20. dict.Add arrT2(i, 1) & "|" & arrT2(i, 6), Array(1, arrT2(i, 2), arrT2(i, 7))
  21. Else
  22. arrIt = dict(arrT2(i, 1) & "|" & arrT2(i, 6)) '将项目放入数组中
  23. arrIt(0) = arrIt(0) + 1 '计算出现次数
  24. arrIt(2) = arrIt(2) + arrT2(i, 7) '添加值
  25. dict(arrT2(i, 1) & "|" & arrT2(i, 6)) = arrIt '将更新后的项目数组放回
  26. End If
  27. End If
  28. Next i
  29. '加载最终数组:
  30. ReDim arFin(1 To dict.count, 1 To 5)
  31. For i = 1 To dict.count
  32. arFin(i, 1) = Split(dict.keys()(i - 1), "|")(0) '客户编号
  33. arFin(i, 3) = Split(dict.keys()(i - 1), "|")(1) '拖欠的延迟
  34. arFin(i, 2) = dict.Items(i - 1)(1) '客户名
  35. arFin(i, 4) = dict.Items(i - 1)(0) '发票数
  36. arFin(i, 5) = dict.Items(i - 1)(2) '发票数
  37. Next i
  38. Set listB = ActiveSheet.OLEObjects("ListBox1").Object: '设置ActiveX列表框
  39. With listB
  40. .ColumnCount = UBound(arFin, 2) '设置列表框的列数
  41. .List = arFin '将数组内容放入列表框
  42. End With
  43. End Sub

已编辑 以使用 Worksheets 而不是表格:

  1. Sub LoadListBoxWithNotExistingCustomNoInSheets()
  2. Dim ws1 As Worksheet, ws2 As Worksheet, arrT1, arrT2, arrUnique, mtch, arrIt, arFin
  3. Dim i As Long, j As Long, dict As Object
  4. Dim listB As msforms.listbox
  5. Set ws1 = ActiveSheet '在此处使用您需要的工作表("My Summary Table")
  6. Set ws2 = ActiveSheet '一样的。我使用相同的工作表,因为我有两个表格,现在转化为范围("My Data source")...
  7. Dim lastR As Long
  8. lastR = ws1.Range("A" & ws1.Rows.Count).End(xlUp).Row '第一个表格的最后一行
  9. arrT1 = ws1.Range("A2:E" & lastR).Value2 '将其内容放入数组以加快处理速度
  10. lastR = ws2.Range("H" & ws2.Rows.Count).End(xlUp).Row '第二个表格的最后一行(注意要使用第一个范围列)
  11. arrT2 = ws1.Range("H2:N" & lastR).Value2 '您应该根据第二个工作表("My Data source")中需要的列来使用范围...
  12. Set dict = CreateObject("Scripting.Dictionary")
  13. '................
  14. '现有代码保持不变...
  15. End Sub

如果与代码注释相关的某些内容不够清楚,请不要犹豫,要求澄清。

英文:

Please, use the next standard way. You must set your lisObjects (tables) from the place (worksheets) where they really exist. The active sheet must contain an ActiveX listbox, named "ListBox1":

  1. Sub LoadListBoxWithNotExistingCustomNo()
  2. Dim tbl1 As ListObject, tbl2 As ListObject, arrT1, arrT2, arrUnique, mtch, arrIt, arFin
  3. Dim i As Long, j As Long, dict As New Scripting.Dictionary
  4. Dim listB As msforms.listbox
  5. 'use here the real sheets where the two involved tables exist:
  6. Set tbl1 = ActiveSheet.ListObjects("T1.") 'the first table Object
  7. Set tbl2 = ActiveSheet.ListObjects("T2.") 'the second table Object
  8. arrT1 = tbl1.DataBodyRange.Value2 'place their contents in an array for faster processing
  9. arrT2 = tbl2.DataBodyRange.Value2
  10. For i = 1 To UBound(arrT1)
  11. dict(arrT1(i, 1)) = vbNullString 'extract the unique Customers numbers
  12. Next i
  13. arrUnique = dict.keys 'place the dictionary keys in an array
  14. dict.RemoveAll 'empty the dictionary to reuse it...
  15. 'load in the dictionary the necessary data:
  16. For i = 1 To UBound(arrT2)
  17. mtch = Application.match(arrT2(i, 1), arrUnique, True)
  18. If Not IsNumeric(mtch) Then
  19. If Not dict.Exists(arrT2(i, 1) & "|" & arrT2(i, 6)) Then
  20. dict.Add arrT2(i, 1) & "|" & arrT2(i, 6), Array(1, arrT2(i, 2), arrT2(i, 7))
  21. Else
  22. arrIt = dict(arrT2(i, 1) & "|" & arrT2(i, 6)) 'place the item in an array
  23. arrIt(0) = arrIt(0) + 1 'count the number of occurrences
  24. arrIt(2) = arrIt(2) + arrT2(i, 7) 'add the values
  25. dict(arrT2(i, 1) & "|" & arrT2(i, 6)) = arrIt 'drop back the updatred ltem array
  26. End If
  27. End If
  28. Next i
  29. 'load the final array:
  30. ReDim arFin(1 To dict.count, 1 To 5)
  31. For i = 1 To dict.count
  32. arFin(i, 1) = Split(dict.keys()(i - 1), "|")(0) 'the customer Number
  33. arFin(i, 3) = Split(dict.keys()(i - 1), "|")(1) 'the aged delay
  34. arFin(i, 2) = dict.Items(i - 1)(1) 'Customer name
  35. arFin(i, 4) = dict.Items(i - 1)(0) 'Count of Invoices
  36. arFin(i, 5) = dict.Items(i - 1)(2) 'Count of Invoices
  37. Next i
  38. Set listB = ActiveSheet.OLEObjects("ListBox1").Object: 'set the ActiveX list box
  39. With listB
  40. .ColumnCount = UBound(arFin, 2) 'set the list box number of columns
  41. .List = arFin 'drop the array content in the list box
  42. End With
  43. End Sub

Edited for using Worksheets instead of Tables:

  1. Sub LoadListBoxWithNotExistingCustomNoInSheets()
  2. Dim ws1 As Worksheet, ws2 As Worksheet, arrT1, arrT2, arrUnique, mtch, arrIt, arFin
  3. Dim i As Long, j As Long, dict As Object
  4. Dim listB As msforms.listbox
  5. Set ws1 = ActiveSheet 'use here the sheet you need ("My Summary Table")
  6. Set ws2 = ActiveSheet 'the same. I am using the same sheet because I had two tables, now transformed in ranges ("My Data source")...
  7. Dim lastR As Long
  8. lastR = ws1.Range("A" & ws1.rows.count).End(xlUp).row 'last row for the former first table
  9. arrT1 = ws1.Range("A2:E" & lastR).Value2 'place their contents in an array for faster processing
  10. lastR = ws2.Range("H" & ws2.rows.count).End(xlUp).row 'last row for the former second table (take care of the first range column TO BE USED)
  11. arrT2 = ws1.Range("H2:N" & lastR).Value2 'you should use your range in terms of necessary columns from second sheet ("My Data source")...
  12. Set dict = CreateObject("Scripting.Dictionary")
  13. '................
  14. 'the existing code remains unchanged...
  15. End Sub

If something not clear enough related to the code comments, do not hesitate to ask for clarifications.

Edit 2

Microsoft Scripting Runtime reference can be added running the next piece of code:

  1. Sub addScrRunTimeRef()
  2. 'Add a reference to 'Microsoft Scripting Runtime':
  3. 'In case of error ('Programmatic access to Visual Basic Project not trusted'):
  4. 'Options->Trust Center->Trust Center Settings->Macro Settings->Developer Macro Settings->
  5. ' check "Trust access to the VBA project object model"
  6. Application.vbE.ActiveVBProject.References.AddFromFile "C:\Windows\SysWOW64\scrrun.dll"
  7. End Sub

huangapple
  • 本文由 发表于 2023年6月29日 16:49:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76579491.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定