【问题标题】:Scripting.Dictionary to fill a column with a string taking in consideration more then 3 criteriaScripting.Dictionary 用字符串填充一列,考虑超过 3 个标准
【发布时间】:2021-01-12 07:29:51
【问题描述】:

我正在尝试用字符串填充 C 列,考虑该行上的消费者是否符合条件之一:

如果消费者满足这些规则之一,则该值应设置为考虑: • 消费者只有 1 笔交易——(已完成) • 消费者有 2 - 4 笔交易,但总交易量 • 消费者级别(基于以下规则)是级别 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 需要检查这两列以查找信息。

CV 列的级别是客户编号位于 H 或/和 G 列时 CW 列的级别是客户端在 AJ 列或/和 AI 列时

我也在这里问(你可以下载文件https://www.ozgrid.com/forum/index.php?thread/1228270-how-to-populate-a-column-with-a-string-taking-in-consideration-5-different-crite/&postID=1239894#post1239941

【问题讨论】:

    标签: excel vba vba7 vba6


    【解决方案1】:

    lvl 设置为 False 的唯一时间是在 For Each k In dict 循环发生之前。

    因此,一旦特定行在该循环中将 lvl 设置为 True,每个后续行也将有 lvl 为 True,因为循环中没有将 lvl 设置回 False。试试这个:

    For Each k In dict
      isConsider = False
      lvl = False
    

    【讨论】:

    • 我做到了,它适用于下拉和级别的标准。太感谢了。但是,对于 2 个有效的标准,代码的第一部分似乎已经超出了 ` 消费者只有 1 笔交易——(已完成)• 消费者有 2 - 4 笔交易,但总交易量 . In this case, is there a way to these 2 criteria separate from the criteria with the date? Maybe 1 code for these 2 criteria 消费者有只有 1 笔交易——(已完成)• 消费者有 2 - 4 笔交易,但总交易量
    • 快速的方法是在isConsider = True 行之后添加lvl = True,这两个条件实际上并不依赖于级别。最好重构您的代码并将一些比较移动到您的 Sub 可以调用的单独函数中
    【解决方案2】:

    您的代码太大。我不认为你会得到你想要的答案,因为发现问题需要时间。因此,我将教你如何构建你的代码,以便能够讨论它的任何部分。请考虑下面的代码。

    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
    

    看看这种结构的优点。

    1. 代码的前 30 多行被压缩成一行。
    2. 这使您可以在主程序中清晰地展开您的叙述。
    3. 与此同时,与创建新工作表相关的所有内容都捆绑到一个单独的过程中,该过程易于测试、易于维护并且在需要时易于提问。

    随着您继续创建项目的叙述,您将到达一个任务是填充 C 列的点。使用上述方法,过滤和消除过程将在一个函数中进行,该函数与函数 @ 一样独立987654323@ 在上面是分开的。它将返回一个值,您将在主过程中将其插入到单元格中。在您目前的设置中,您甚至无法确定该操作发生的位置(我们也不能)。如果您更改结构以使其更加透明,您就不会有这样的问题,我们很乐意为您提供帮助。

    【讨论】:

    • 你说的是代码吗? (这里不知道怎么附加文件,所以我在[ozgrid.com/forum/index.php?thread/…上添加了文件。我会改的。说实话,这段代码只是Big宏的一部分,所以它需要在一个SUB(已经存在,在我完成工作表“交互审查”的代码后,其他选项卡会有更多代码)。我会做你告诉我的更改,学习让我的代码更具可读性总是好的。
    • 本网站不支持附加您的文件,因为它想切中要害。如果你的观点不能在 25 行代码中表达出来,你的问题还没有被发现:找到它,我们将帮助你解决它。但是,我从 oxgrid 下载了您的文件,然后在阅读了 25 行后放弃了。我发现它们除了是更大程序的一部分之外没有任何问题 - 程序太大。所以我向你展示了如何使用函数。如果你有逻辑地组织你的代码,你可以剥离好的部分并揭示问题。
    • 谢谢,我正在这样做,老实说,代码看起来和阅读起来更好。我还在学习如何使用 VBA,感谢您的意见和建议。
    猜你喜欢
    • 2013-09-27
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    • 2013-05-26
    • 2018-04-29
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多