Scripting.Dictionary 考虑超过 3 个条件用字符串填充列
Scripting.Dictionary to fill a column with a string taking in consideration more then 3 criteria
我正在尝试用字符串填充 C 列 consider if the consumer on the row matches one of the criteria:
如果消费者满足这些规则之一,则值应设置为 Consider:
• 消费者只有 1 笔交易——(已完成)
• 消费者有 2 - 4 笔交易,但总交易量 < 10,000 美元 ---(已完成)
• 消费者级别(基于以下规则)为 2 级或 3 级 ---(此信息位于 CV 和 CW 列)
• 如果下拉列表为 60 天且最大交易日期早于 30 天
• 如果下拉列表为 1 年且最大交易日期早于 90 天
• 如果下拉列表为 5 年且最大交易日期早于 180 天
'Interdction Review Tab, column C
Sheets("Interdiction Review").Columns(3).Font.Bold = True
Sheets("Interdiction Review").Columns(3).HorizontalAlignment = xlCenter
'Consumer has only 1 Transaction, the value on Interdiction Review Tab on Column C will be Consider
Dim wsStart As Worksheet, lastRow1 As Long, wsFinal As Worksheet
Dim dict As Object, rw As Range, v, v2, k, m, lin
Dim wsSSart As Worksheet
Dim dateDifference As Long
Dim SStartSelection As String
Dim isConsider As Boolean
Dim valid_col(1) As Integer
Dim lvl As Boolean
Set wsSSart = ActiveWorkbook.Sheets("SStart")
Set wsStart = ActiveWorkbook.Sheets("Start")
Set wsFinal = ActiveWorkbook.Sheets("Interdiction Review")
lastRow1 = wsStart.Cells(Cells.Rows.Count, "A").End(xlUp).Row
Set dict = CreateObject("Scripting.Dictionary")
SStartSelection = wsSSart.Cells(7, "A").Value
lvl = False
For Each rw In wsStart.Range("A2:AJ" & lastRow1).Rows
v = rw.Cells(8).Value
v2 = rw.Cells(36).Value
If Len(v) = 0 Or Len(v2) = 0 Then
v = rw.Cells(7).Value
v2 = rw.Cells(35).Value
End If
dict(v) = dict(v) + 1
dict(v2) = dict(v2) + 1
Next rw
For Each k In dict
isConsider = False
m = Application.Match(k, wsFinal.Columns(1), 0)
wsFinal.Cells(m, 7).FormulaArray = wsFinal.Cells(m, 7).Formula
dateDifference = DateDiff("D", wsFinal.Cells(m, 7).Value, Date)
If dict(k) = 1 Then
isConsider = True
ElseIf dict(k) >= 2 And dict(k) <= 4 And wsFinal.Cells(m, 6).Value <= 10000 Then
isConsider = True
End If
If StrComp(SStartSelection, "60 Days") = 0 And dateDifference > 30 Then
isConsider = True
ElseIf StrComp(SStartSelection, "1 Year") = 0 And dateDifference > 90 Then
isConsider = True
ElseIf StrComp(SStartSelection, "5 Years") = 0 And dateDifference > 180 Then
isConsider = True
End If
'Client number
If wsStart.Cells(2, 8) <> "" Then
valid_col(0) = 8
valid_col(1) = 36
Else
valid_col(0) = 7
valid_col(1) = 35
End If
'Level verification
For lin = 2 To lastRow1
If wsStart.Cells(lin, valid_col(0)) = k Then
If wsStart.Cells(lin, 100).Value = "Level 2" Or wsStart.Cells(lin, 100).Value = "Level 3" Then
lvl = True
Exit For
End If
End If
If wsStart.Cells(lin, valid_col(1)) = k Then
If wsStart.Cells(lin, 101).Value = "Level 2" Or wsStart.Cells(lin, 101).Value = "Level 3" Then
lvl = True
Exit For
End If
End If
Next lin
If isConsider And lvl Then
If Not IsError(m) Then wsFinal.Cells(m, 3).Value = "Consider"
End If
Next k
End Sub
我的代码似乎在错误的列中查找客户级别。前任:
客户编号 3 位于 H 列,因此代码需要检查 CV 列以了解级别
客户编号 3 也位于 AJ 列,代码需要检查 CW 列以查看级别。
如果客户端位于两列并且 cod 需要检查两列以查找信息。
当客户编号在H列时,CV列的水平or/and G
CW 列的级别是当客户端在 AJ 列 or/and AI
上时
唯一一次 lvl
设置为 False 是在 For Each k In dict
循环发生之前。
因此,一旦特定行在该循环中将 lvl
设置为 True,每个后续行也将 lvl
为 True,因为循环中没有任何内容可设置 lvl
回到错误。试试这个:
For Each k In dict
isConsider = False
lvl = False
您的代码太大。我不认为你会得到你想要的答案,因为找到问题需要时间。因此,我将教您如何以能够讨论代码的任何部分的方式构建代码。请考虑以下代码。
Sub NewTest()
' 093
Dim WsIR As Worksheet
Set WsIR = CreateWsIR()
Worksheets("Start").Activate ' probably not useful
End Sub
Private Function CreateWsIR() As Worksheet
' 093
Dim Fun As Worksheet ' = Function return object under preparation
Set Fun = Worksheets.Add ' Excel will make this the ActiveSheet
With Fun
.Name = "Interdiction Review"
.Move After:=Worksheets("Start")
' format your sheet here
End With
Set CreateWsIR = Fun
End Function
看看这个结构的优点
- 您的代码的前 30 多行被压缩成一行。
- 这使您可以在主要过程中清楚地展开叙述。
- 与此同时,与创建新工作表相关的所有内容都被捆绑到一个单独的过程中,该过程易于测试、易于维护并且在需要时易于提出问题。
随着您继续创建项目的叙述,您将到达任务是填充 C 列的地步。使用上述方法,过滤和消除过程将在一个独立的函数中进行,就像函数 CreateWsIR
在上面是分开的。它将 return 一个值,您将在主过程中将其插入到单元格中。在您目前的设置中,您甚至无法确定该操作发生的位置(我们也不能)。如果您更改结构以使其更加透明,您就不会遇到这样的问题,我们很乐意提供帮助。
我正在尝试用字符串填充 C 列 consider if the consumer on the row matches one of the criteria:
如果消费者满足这些规则之一,则值应设置为 Consider: • 消费者只有 1 笔交易——(已完成) • 消费者有 2 - 4 笔交易,但总交易量 < 10,000 美元 ---(已完成) • 消费者级别(基于以下规则)为 2 级或 3 级 ---(此信息位于 CV 和 CW 列) • 如果下拉列表为 60 天且最大交易日期早于 30 天 • 如果下拉列表为 1 年且最大交易日期早于 90 天 • 如果下拉列表为 5 年且最大交易日期早于 180 天
'Interdction Review Tab, column C
Sheets("Interdiction Review").Columns(3).Font.Bold = True
Sheets("Interdiction Review").Columns(3).HorizontalAlignment = xlCenter
'Consumer has only 1 Transaction, the value on Interdiction Review Tab on Column C will be Consider
Dim wsStart As Worksheet, lastRow1 As Long, wsFinal As Worksheet
Dim dict As Object, rw As Range, v, v2, k, m, lin
Dim wsSSart As Worksheet
Dim dateDifference As Long
Dim SStartSelection As String
Dim isConsider As Boolean
Dim valid_col(1) As Integer
Dim lvl As Boolean
Set wsSSart = ActiveWorkbook.Sheets("SStart")
Set wsStart = ActiveWorkbook.Sheets("Start")
Set wsFinal = ActiveWorkbook.Sheets("Interdiction Review")
lastRow1 = wsStart.Cells(Cells.Rows.Count, "A").End(xlUp).Row
Set dict = CreateObject("Scripting.Dictionary")
SStartSelection = wsSSart.Cells(7, "A").Value
lvl = False
For Each rw In wsStart.Range("A2:AJ" & lastRow1).Rows
v = rw.Cells(8).Value
v2 = rw.Cells(36).Value
If Len(v) = 0 Or Len(v2) = 0 Then
v = rw.Cells(7).Value
v2 = rw.Cells(35).Value
End If
dict(v) = dict(v) + 1
dict(v2) = dict(v2) + 1
Next rw
For Each k In dict
isConsider = False
m = Application.Match(k, wsFinal.Columns(1), 0)
wsFinal.Cells(m, 7).FormulaArray = wsFinal.Cells(m, 7).Formula
dateDifference = DateDiff("D", wsFinal.Cells(m, 7).Value, Date)
If dict(k) = 1 Then
isConsider = True
ElseIf dict(k) >= 2 And dict(k) <= 4 And wsFinal.Cells(m, 6).Value <= 10000 Then
isConsider = True
End If
If StrComp(SStartSelection, "60 Days") = 0 And dateDifference > 30 Then
isConsider = True
ElseIf StrComp(SStartSelection, "1 Year") = 0 And dateDifference > 90 Then
isConsider = True
ElseIf StrComp(SStartSelection, "5 Years") = 0 And dateDifference > 180 Then
isConsider = True
End If
'Client number
If wsStart.Cells(2, 8) <> "" Then
valid_col(0) = 8
valid_col(1) = 36
Else
valid_col(0) = 7
valid_col(1) = 35
End If
'Level verification
For lin = 2 To lastRow1
If wsStart.Cells(lin, valid_col(0)) = k Then
If wsStart.Cells(lin, 100).Value = "Level 2" Or wsStart.Cells(lin, 100).Value = "Level 3" Then
lvl = True
Exit For
End If
End If
If wsStart.Cells(lin, valid_col(1)) = k Then
If wsStart.Cells(lin, 101).Value = "Level 2" Or wsStart.Cells(lin, 101).Value = "Level 3" Then
lvl = True
Exit For
End If
End If
Next lin
If isConsider And lvl Then
If Not IsError(m) Then wsFinal.Cells(m, 3).Value = "Consider"
End If
Next k
End Sub
我的代码似乎在错误的列中查找客户级别。前任: 客户编号 3 位于 H 列,因此代码需要检查 CV 列以了解级别 客户编号 3 也位于 AJ 列,代码需要检查 CW 列以查看级别。 如果客户端位于两列并且 cod 需要检查两列以查找信息。
当客户编号在H列时,CV列的水平or/and G CW 列的级别是当客户端在 AJ 列 or/and AI
上时唯一一次 lvl
设置为 False 是在 For Each k In dict
循环发生之前。
因此,一旦特定行在该循环中将 lvl
设置为 True,每个后续行也将 lvl
为 True,因为循环中没有任何内容可设置 lvl
回到错误。试试这个:
For Each k In dict
isConsider = False
lvl = False
您的代码太大。我不认为你会得到你想要的答案,因为找到问题需要时间。因此,我将教您如何以能够讨论代码的任何部分的方式构建代码。请考虑以下代码。
Sub NewTest()
' 093
Dim WsIR As Worksheet
Set WsIR = CreateWsIR()
Worksheets("Start").Activate ' probably not useful
End Sub
Private Function CreateWsIR() As Worksheet
' 093
Dim Fun As Worksheet ' = Function return object under preparation
Set Fun = Worksheets.Add ' Excel will make this the ActiveSheet
With Fun
.Name = "Interdiction Review"
.Move After:=Worksheets("Start")
' format your sheet here
End With
Set CreateWsIR = Fun
End Function
看看这个结构的优点
- 您的代码的前 30 多行被压缩成一行。
- 这使您可以在主要过程中清楚地展开叙述。
- 与此同时,与创建新工作表相关的所有内容都被捆绑到一个单独的过程中,该过程易于测试、易于维护并且在需要时易于提出问题。
随着您继续创建项目的叙述,您将到达任务是填充 C 列的地步。使用上述方法,过滤和消除过程将在一个独立的函数中进行,就像函数 CreateWsIR
在上面是分开的。它将 return 一个值,您将在主过程中将其插入到单元格中。在您目前的设置中,您甚至无法确定该操作发生的位置(我们也不能)。如果您更改结构以使其更加透明,您就不会遇到这样的问题,我们很乐意提供帮助。