【问题标题】:capture data from a cell and paste the value into another cell on a different worksheet从单元格捕获数据并将值粘贴到不同工作表上的另一个单元格中
【发布时间】:2015-11-16 21:56:18
【问题描述】:

我让这件事在我的脑海中变得比它必须的更具挑战性,但由于我最近没有使用 vba 或 excel,所以我以此为借口。请不要质疑方法:) 因为这只是我试图消除的一小步,以节省一些时间,直到我可以重做整个过程。我会做相反的事情,但这是他们正在使用的某种发票......

我认为宏或函数是需要的,而不是公式,因为工作表 2 上的数据每个月都会发生变化,而且我没有可以参考的日期。

我想做的事:

我在工作表 2 上有一个单元格,每月更改一次。我想每月将工作表 2 中的单元格的值放入工作表 1 中的一个单元格中,她每个月都会更改它。

每个月都将在 A 列中表示,并且该月工作表 2 中的单元格的值需要放在 B 列中。

Column A         Column B
12/5/2012        $3,459,877.81 
1/8/2013         $9,360,785.62 
2/8/2013        
3/8/2013        
4/8/2013        

因此,当她更改 2 月份的工作表 1 时,该数字将填充到 2/8 旁边,依此类推。我想在她保存文档时这样做,或者让它成为她可以点击的快捷方式,或者只是废弃它并告诉她这不值得。

【问题讨论】:

  • 工作表 1 上的单元格是否在她更改的月份每月仅更改一次?换句话说,当二月到来时,她在那个月更改了 Sheet1:A1 的值,这需要输入到二月日期旁边的 Sheet2:B3 中吗?
  • 这实际上有一个优雅的解决方案,您不必在其他单元格中存储任何单元格值。我将在下面发布我的模型。
  • 答案添加在下面。让我知道这是否有帮助

标签: excel vba


【解决方案1】:

为 Cell 命名以供您参考可以通过将 Target 参数传递给 Worksheet_Change 函数来做一些简洁的事情:

'Add this function to the sheet that has the cell being
'+changed by the user (Sheet 2)
Private Sub Worksheet_Change(ByVal Target As Range) 
    Dim strCellName As String
    strCellName = "ChangeMe"
    'If the cell we changed was the ChangeMeCell
    If Target.Address = Sheet2.Range(strCellName).Address Then
        'Store value
        Dim intLastRow, intValue As Integer
        intValue = Range(strCellName).Value

        'Find the cell in Sheet 1 Column A that matches this month
        intLastRow = Sheet1.Range("A:A").End(xlDown).Row
        For Each cl In Sheet1.Range("A1:A" & intLastRow).Cells
            'Ensure cell value is date
            If IsDate(cl.Value) Then

                'If date is today's date
                'Note that Math.Round(<date>, 0 ) essentially removes the time
                '+from any date value so #01/02/03 04:05:06# becomes #01/02/03#
                If Math.Round(cl.Value,0) = Math.Round(Now,0) Then
                    'Update column B's value
                    Sheet1.Range("B" & cl.Row).Value = intValue
                End If
            End If
        Next
    End If
End Sub

这假设您的工作表布局在 Sheet1 中具有“发票值”,并且在 Sheet2 中更改了单元格。您需要为该单元格命名。

使用功能栏左侧的单元格名称框调用更改“ChangeMe”的单元格或您希望将其更改为的任何内容,在函数的第一行更新该单元格名称,此函数将完成所有休息。

请务必注意,必须针对您的系统区域正确格式化日期。以确保它显示正确的月份 - 将它们格式化为 LongDate 以便您可以将它们视为 2013 年 3 月 8 日而不是 03/08/13,这可能会随着时间的推移而变得混乱。 作为一名英国程序员,约会是我生命中的祸根!

编辑:如果您仍需要在任一日期值中减去或添加一个月,我已更新代码以按完整日期减去时间来比较日期,而不是之前的每月比较,只需使用DateAdd("m", &lt;date&gt;, &lt;value&gt;) 加减月份即可。

编辑:DatePart Function page 对于那些想了解更多有关 DatePart() 的人来说是一个有用的资源

【讨论】:

  • 这确实有效,但我想要输入的数字。而不是改变的数字。至少......这就是我想象它的工作方式。我想如果我在她去更改当前月份时使用它,这可能对我有用。当她这样做时,可以将更改的旧数据放在前一个月,依此类推。我需要测试一下。
  • @blue- 如何获取上个月的日期?或更好的值以匹配她正在更改的单元格的日期。例如,她将更改 A 列中日期旁边的 B 列中的数据。该数据提供给其他工作表。如果我能弄清楚如何根据该单元格获取该数据,那我就可以走了。本质上是宏内的 vlookup。希望这是有道理的。
  • 在检查今天的月份是否与列中的月份相同时,在 Now 变量上使用 dateadd,返回一个月使用 -1。 If DatePart("m", cl.Value) = DatePart("m", DateAdd("m", -1, Now) ) 那么
  • 我已经更新了我的答案以更好地匹配需要相等的日期,您仍然可以使用 DatePart 和 DateAdd 来根据需要更改日期。
  • 如此接近!这也有效。但是,现在我越来越挑剔了。她可以输入数据的日期将是几天或一周后。因此,在 3/18,她可能会为 3/15 开具发票。我需要它来捕捉 3/15 的日期。但它会立即更新号码,这是完美的!
【解决方案2】:

在我的示例中,我使用单元格G4 作为将由您的同事更新的单元格。您必须有某种方法来保持 G4 的原始值,以便判断它何时被更改。执行此操作的简单方法是选择一些用户看不见的单元格并将数字存储在那里,以便您以后可以引用它。这里我选择了单元格AA1。以下代码必须专门添加到Sheet2,因为它只需要监视该工作表上的更改事件,以便在更新G4 时触发。

Private Sub Worksheet_Change(ByVal Target As Range)
    If Range("G4") <> Range("AA1") Then
        Dim lastRow As Long

        Range("AA1") = Range("G4")
        lastRow = Worksheets("Sheet1").UsedRange.Rows.Count

        Worksheets("Sheet1").Cells(lastRow + 1, 1).Value = Date
        Worksheets("Sheet1").Cells(lastRow + 1, 2).Value = Range("AA1")

    End If
End Sub

请记住,对于此任务来说,这是一种非常“快速而肮脏”的方法,因为它没有错误处理程序或它的工作方式具有很大的灵活性。


编辑 --

此处引用了您可以使用的另一种方法,可以简单地检查给定单元格是否已更改,而无需验证值的差异。

 Private Sub Worksheet_Change(ByVal Target As Range)
     If Not Application.Intersect(Range("G4"), Range(Target.Address)) Is Nothing Then
        Dim lastRow As Long
        Range("AA1") = Range("G4")
         lastRow = Worksheets("Sheet1").UsedRange.Rows.Count

         Worksheets("Sheet1").Cells(lastRow + 1, 1).Value = Date
         Worksheets("Sheet1").Cells(lastRow + 1, 2).Value = Range("AA1")
     End If
 End Sub

【讨论】:

  • 感谢您的帮助。也许我做错了什么才能让它发挥作用。我不明白将 g4 的值放在 aa1 中有何作用。当g4改变时,如果在AA1单元格中我做=G4,aa1也会改变。这似乎是一个额外的步骤。我想做的是当她改变它时捕获G4。老实说,我认为这不值得我付出时间。它确实看起来很脏,而且出错的可能性太大。
  • 将值放入 AA1 以便在她更改旧值时引用它。您不想每次更改页面时都更新页面除非它在 G4 上发生更改。它检查 G4 和 AA1 是否不再相同,如果不同则运行代码。你可以通过explicitly checking which cells are changed 来做,但我认为这是一种更复杂的方法。
  • 我错过了如果单元格相同并且 AA1 引用 G4 时脚本将如何查看更改。我想这就是我被挂断的地方
  • 我确实认为您发送给我的链接实际上可能有效,因为几个单元格会发生变化。我也许可以在宏运行之前再添加几个实例进行检查。
  • AA1 不直接引用 G4,但如果 G4 发生更改,则 AA1 会重置以匹配它,但前提是它已经执行了 if 块。使用 AA1 执行此操作还可以让您在Sheet1 更改后使用先前的值更新它(尽管您希望在代码末尾而不是开头重置 AA1)。如果您要监视多个单元格的更改,我认为链接代码肯定会更好。
【解决方案3】:

现在,我可以从单元格中的公式中获取值,并将其放在另一个工作表的不同单元格中。这是我的最终产品:

Private Sub Worksheet_Calculate()

  Dim strCellName As String
   strCellName = "ChangeMe"
   If Sheets("Application of Moneys").Range(strCellName).Address <> PrevVal Then
    Dim intLastRow, intValue As Long
    intValue = Range(strCellName).Value

   'Find the cell in Sheet 1 Column A that matches this month
    intLastRow = Sheets("Certificate 1").Range("B:B").End(xlDown).Row
    For Each cl In Sheets("Certificate 1").Range("B13:B25" & intLastRow).Cells
        'Ensure cell value is date
        If IsDate(cl.Value) Then

            'If date is today's date
            'Note that Math.Round(<date>, 0 ) essentially removes the time
            '+from any date value so #01/02/03 04:05:06# becomes #01/02/03#
            If DatePart("m", cl.Value) = DatePart("m", Now()) Then
                'Update column B's value
                Sheets("Certificate 1").Range("H" & cl.Row).Value = intValue
            End If
        End If
    Next
End If
End Sub

【讨论】:

    猜你喜欢
    • 2020-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    • 1970-01-01
    相关资源
    最近更新 更多