【问题标题】:Excel Checkboxes and ArraysExcel 复选框和数组
【发布时间】:2020-08-12 18:23:50
【问题描述】:

我正在为与我合作的团队创建一个项目跟踪器,并且我想将单个项目的所有项目信息复制到一行中。然后该行中的 2 列将是“任务完成”和“完成日期”。

目前我正在使用数据验证列表在任务完成单元格中选择“完成”。列出“完成”时,“完成日期”将自动填充“今天”日期。我只是用excel中的简单函数来实现这一点。

然后我创建了 VBA 代码,以便单击命令按钮,它将突出显示行中的特定单元格,复制这些单元格,将它们粘贴到空工作表中,然后清除任务和日期完成单元格。

我已经让这些功能中的大部分都可以使用,但我遇到了障碍,让 excel 仅将空白工作表中的数据复制到空行中(A1、A2、A3 行等)。我不确定如何让代码将数据复制到空行中。我知道它可以通过使用变量(i)和循环来实现。

我的另一个问题是,我最初想使用复选框而不是经过验证的列表,但似乎在使用复选框的格式方面存在问题。如果我的行大小必须更改以适合文本,复选框将挤满其他单元格。这只是 excel 中表单/activeX 的缺陷,还是我错过了大局的一部分?

我尝试使用数组来检查“任务完成”列,而不是使用单独的 If 语句来添加日期。附上我的代码示例:

Dim pjt As Worksheet
Dim datawks As Worksheet
Dim myBook As Workbook  'define worksheets and workboook
Set myBook = Excel.ActiveWorkbook
Set pjt = myBook.Sheets("Project Tracker")
Set datawks = myBook.Sheets("DATA")

Dim tskarray(16) As String
     tskarray(0) = Range("K4")
     tskarray(1) = Range("k5")
     tskarray(2) = Range("k6")
     tskarray(3) = Range("k7")
     tskarray(4) = Range("k8")
     tskarray(5) = Range("k9")
     tskarray(6) = Range("k10")
     tskarray(7) = Range("k11")
     tskarray(8) = Range("k12")
     tskarray(9) = Range("k13")
     tskarray(10) = Range("k14")
     tskarray(11) = Range("k15")
     tskarray(12) = Range("k16")
     tskarray(13) = Range("k17")
     tskarray(14) = Range("k18")
     tskarray(15) = Range("k19")
     tskarray(16) = Range("k20")


        If tskarray(0) = "Complete" Then
            Range("A4,B4,D4,F4,G4,J4,L4").Select
            Selection.Copy
            datawks.Select
            datawks.Cells(1, 1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, skipblanks _
                :=False, Transpose:=False
            Sheets("Project Tracker").Select
            Application.CutCopyMode = False
            pjt.Range("J4,K4").Select
            Selection.ClearContents

        Else
        Debug.Print ("No Task to Complete")
        End If

【问题讨论】:

  • 您是否尝试在单元格 K4 到 K20 中检查“完成”一词?
  • 查看 Range.Offest 和 Range.End 命令。我认为他们是你正在寻找的东西。此外,您还可以设置范围变量而不是使用数组或(更重要的是)而不是选择范围。你似乎是那种重视自我提升的人,所以继续吧。如果您发现任何困难或希望获得完整的示例,请直接说。我很乐意为您编写完整的注释代码。
  • 您能否阐明“代码将数据复制到空行中”的意思?顺便说一句,您可以在一行中为数组分配一个范围。
  • @dwirony - Yes 检查 K4-K20 Complete 然后用当前日期填充它旁边的单元格。
  • @evilbluemonkey 感谢您的提示,我一定会研究这些命令。我不反对一些我可以用作参考的示例代码。我确实觉得阅读代码比编写代码更容易。

标签: excel vba checkbox activex


【解决方案1】:

因此,在此线程上每个人的帮助下,尤其是 @Samuel Everson 和家里的一些朋友,我能够让我的代码按预期工作。我想发布工作代码以获取改进建议或其他可能有类似问题的建议。代码如下:

Dim LastRow As Long
Dim LastCol As Long
Dim i As Integer
Dim j As Range


RowCount = 3
ColCount = 3
i = 1
Set j = Range("a1").End(xlDown)

    For ArrayCount = LBound(tskarray) To UBound(tskarray)
        RowCount = RowCount + 1
        ColCount = ColCount + 1

            If tskarray(ArrayCount) = "Complete" Then
                Do While i < 7
                For Each TargetCell In pjt.Range("A" & RowCount & ": L" & RowCount)
                    If TargetCell.Column = 3 Or TargetCell.Column = 5 Or TargetCell.Column = 8 Or TargetCell.Column = 9 Or TargetCell.Column = 11 Then

                    Else

                        With datawks
                         .Range("A1").End(xlUp).Offset(j, i) = TargetCell.Value
                         i = i + 1

                        End With

                    End If

        Next TargetCell
        j = j + 1
        Loop
        i = 1
        'pjt.Range("J" & RowCount & ":K" & RowCount).ClearContents
        End If
        Next ArrayCount

【讨论】:

    【解决方案2】:

    我相信这将完成您的任务(至少根据您的问题),并结合您提到的循环。

    Dim tskarray() As String
    ReDim tskarray(0 To 16)
    Dim ArrayElementCount As Long
    Dim RowCount As Long
    RowCount = 3 'this will increment by 1 at the start of the loop so after the last iteration it will end at 16 not 17
    
    For ArrayElementCount = 0 To UBound(tskarray)
        RowCount = RowCount + 1
        tskarray(ArrayElementCount) = pjt.Range("K" & RowCount) 'Assuming on pjt sheet.
    Next ArrayElementCount
    
    Dim TargetCell As Range
    Dim LastRow As Long
    RowCount = 3
    For ArrayElementCount = 0 To UBound(tskarray)
        RowCount = RowCount + 1
        If tskarray(ArrayElementCount) = "Complete" Then
            For Each TargetCell In pjt.Range("A" & RowCount & ": L" & RowCount) 'Also assuming on pjt sheet
            If TargetCell.Column = 3 Or TargetCell.Column = 5 Or TargetCell.Column = 8 Or TargetCell.Column = 9 Or TargetCell.Column = 11 Then
                    'Ignore columns C, E, H, I and K
                Else
                    With datawks
                        LastRow = .Cells(Rows.Count, 1).End(xlUp).Row + 1
                        .Cells(LastRow, 1).Value = TargetCell.Value
                    End With
                End If
            Next TargetCell
            pjt.Range("J" & RowCount & ":K" & RowCount).ClearContents 'Change the column letters if the range should be bigger. 
        Else
            Debug.Print ("No Task to Complete")
        End If
    Next ArrayElementCount
    

    【讨论】:

    • 这非常有帮助。能够单步执行该代码并查看结果确实有助于了解循环的功能。
    • 所以我修改了代码以将 TargetCell.Value 应用于行而不是列。我使用.Cells(1, LastCol).Value = TargetCell.Value 来实现这一点。然后我想像.Cells(LastRow, 1).Value 的运行方式一样转到下一行,但只有在输入了来自 pjt 工作表行的所有数据之后。因此,例如,排除单元格的第 4 行将输入到 datawks 的第 2 行。然后 pjt 的第 5 行输入到 datawks 的第 3 行。
    • 如果您希望它在每次迭代时继续递减行(必要时)添加最后一行,所以.Cells(LastRow, LastCol).Value = TargetCell.Value。如果您正在沿行写入值并且它总是是相同长度的单元格(例如,意味着 G 列始终是最后一个),您可以根据该列而不是 A 列设置最后一行,这样您仍然可以在与我的代码相同的位置分配它的值,但一旦您将值放入 A 列,它最终不会跳过整行。
    猜你喜欢
    • 2015-01-23
    • 1970-01-01
    • 1970-01-01
    • 2011-09-23
    • 2018-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    相关资源
    最近更新 更多