【问题标题】:Display last updated row in overview page - Excel在概览页面中显示最后更新的行 - Excel
【发布时间】:2013-02-01 23:28:54
【问题描述】:

我在 Excel 中有一个共享工作簿,其中包含几张工作表和一个名为概览的主工作表。

例如概览 - Sheet1 - Sheet2 - Sheet 3

在工作表 1/2/3 中,我或其他人用一些数据更新行。

很难跟踪工作簿中的最后一个条目(因为我需要在所有工作表中搜索),所以我想在我的概览页面中创建一个“前 10 名”动态列表,它会自动更新包含工作簿中最后 10 个更新的行。

有人可以帮我解决这个问题吗?

这是一个例子:

谢谢!

【问题讨论】:

  • 请提供更多详细信息,至少每张纸上的行尺寸,例如A:E 列或类似列。还有...What have you tried?
  • 嗨,尺寸将适用于整个页面,以捕获使用信息更新的任何新行。 A1:R1 - 列 A1:A10000 - 行 请参阅我上面的链接以获得说明。我没有尝试太多,因为我不确定如何做到这一点..不确定excel是否可以做到这一点..谢谢
  • 让我们等待承诺的解决方案)我很确定它将基于 VBA SheetChange 事件。
  • @PeterL。 - 你是对的。我希望等待是值得的......虽然我使用Worksheet_Change,如果你想对它挑剔的话。 :-)
  • @Floris 干得好。希望你能得到你应得的接受

标签: excel list vba rows auto-update


【解决方案1】:

最干净的解决方案是这样的:

在工作簿级别添加事件处理程序以捕获正在更改的单元格;在处理程序中,执行以下操作:

  • 关闭事件处理(您将要更改工作表并且不想进入无限循环)!
  • 关闭屏幕更新
  • 在前页的第 1 行中插入一行
  • 在此处输入已更改行的副本
  • 在附加列中添加更改用户以及日期/时间(如果您愿意)
  • 返回原来的选择
  • 开启屏幕更新
  • 开启事件处理

这里是分步说明(示例文件可以从http://www.floris.us/SO/download/XLexample.xlsm 下载) - 假设 PC 上使用 Excel 2010。其他版本大多会有细微差别...

  1. 确保您的文件保存为 .xlsm 格式 - 这告诉 Excel 有宏
  2. 在添加所有这些内容之前创建文件的备份 - 以防您搞砸了!
  3. 关闭所有其他文件(暂时) - 查看之前的评论
  4. 确保您的文件有四个工作表:“summary”、“widgets”、“things”和“stuff”(或任何您认为有帮助的名称 - 我将使用这些名称而不是“Sheet1”等来引用它们.)
  5. 右键单击“小部件”选项卡,然后选择“查看代码”
  6. 将以下代码粘贴到工作表的“代码”窗口中:

Private Sub Worksheet_Change(ByBal Target as Range)
  On Error GoTo procErr
  process_change Target
  Exit Sub

procErr:
  MsgBox "Got an error: " & Err.Description
  Err.Clear
  Application.EnableEvents = True
End Sub`
  1. 对每个“数据”工作表重复上述步骤:“事物”和“东西”(但不适用于“摘要”)
  2. 当 Visual Basic 编辑器打开时(您在此处进行所有粘贴操作),使用 Insert->Module 在工作簿中插入一个新代码模块
  3. 将以下代码粘贴到您创建的模块中:

.

Option Explicit

Sub process_change(ByVal Target As Range)
' when a cell is changed on one of the worksheets, this function is called
' it copies the most recently changed row
' and inserts it on the second line of the "summary" worksheet
' right below the headers
' if the headers include "changed by" and/or "last changed" (exactly)
' then that column will be updated with the (windows) user name and date, respectively
' similarly, if a column named "source" exists, it will contain the address of the row
' (sheet name / row number). In that case, if there was an earlier occurrence of the same row
' (multiple edits), the earlier occurence is removed
' you may use this code as is - but there is no warranty as to its useability

Dim s1 As Worksheet, s2 As Worksheet
Dim srcAddress As String
Dim oldSelection As Range

' don't update screen during processing - prevent "flickering"
Application.ScreenUpdating = False ' set to True when debugging

' don't accept events until we're done
Application.EnableEvents = False

' store old selection
Set oldSelection = Selection

Dim ri As Integer           ' index of changed row
Dim rowAddress As String
ri = Target.Row
rowAddress = ri & ":" & ri  ' address of changed row

if ri = 1 Then
  Application.EnableEvents = True
  Exit Sub                  ' don't record changes to the headers
End If

Range(rowAddress).Select
Selection.Copy              ' copy changed row

Set s1 = ActiveSheet        ' know where we will go back to
srcAddress = s1.Name & ":row" & ri ' full address to be used later

Set s2 = ActiveWorkbook.Sheets("summary")

s2.Range("2:2").Insert      ' add a row at the top of the list
s2.Select                   ' activate sheet where we want to paste
Range("A2").Select          ' leftmost cell of column
ActiveSheet.Paste           ' paste the entire changed row

' optionally, we can add "source", "last changed" and "changed by"
' we do this if appropriately named columns exist
' slightly clumsy code to catch errors...
Dim lcCol
If Not IsError(Application.Match("last changed", Range("1:1"), 0)) Then
  lcCol = Application.Match("last changed", Range("1:1"), 0)
  Range("A2").Offset(0, lcCol - 1).Value = Date
End If

Dim cbCol
If Not IsError(Application.Match("changed by", Range("1:1"), 0)) Then
  cbCol = Application.Match("changed by", Range("1:1"), 0)
  Range("A2").Offset(0, cbCol - 1).Value = UserName
End If

Dim srcCol
If Not IsError(Application.Match("source", Range("1:1"), 0)) Then
  srcCol = Application.Match("source", Range("1:1"), 0)
  ' find earlier entry regarding this row...
  Columns("A:A").Offset(0, srcCol - 1).Select
  Dim sf As Range
  Set sf = Selection.Find(What:=srcAddress, After:=ActiveCell, LookIn:= _
        xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:= _
        xlNext, MatchCase:=False, SearchFormat:=False)
  If Not sf Is Nothing Then
  ri = sf.Row
  rowAddress = ri & ":" & ri  ' address of changed row
  Range(rowAddress).Select
  Selection.Delete
  End If
  Range("A2").Offset(0, srcCol - 1).Value = srcAddress
End If

s1.Activate                     ' go back to original worksheet
Application.CutCopyMode = False ' get rid of the "marching ants"
oldSelection.Select             ' select the previous selection "like nothing happened"

' and turn on screenupdating and events...
Application.EnableEvents = True
Application.ScreenUpdating = True

End Sub

Sub eventsOn()
Application.EnableEvents = True
End Sub

Public Function UserName()
' note - this function only works on PC
  UserName = Environ$("UserName")
End Function

完成所有这些后,您现在可以在工作表中放置标题 - 在所有四个工作表中使用相同的列标题。在第一个(摘要)表中,您可以选择再添加三个标题:这些标题不应与您使用的其他标题相同,并且被称为(确切地 - 没有额外的空格,大写,...):source,@ 987654327@,changed by

如果最后三个列标题不存在,则行为如下:

每次您对三个工作表中的一个进行更改时,所做更改的行将被复制到摘要表的第一行,标题下方。其他所有内容都会下移一排。

如果您添加“来源”列,将会发生两件事:来源(工作表名称:行号)将添加到该列中,并且将删除同一来源(同一行)的任何先前条目。因此,您只会看到给定行的“最新更改”。

如果添加“更改者”,您将获得最后一次更改的用户的名称; “上次更改”标题将包含上次更改的日期。

如果您能从这里解决问题,请告诉我 - 如果您遇到困难,请使用我在上面链接的示例电子表格来指导您。

【讨论】:

  • 您好,对VBA不是很熟悉,请问可以在excel中使用一些公式吗?我正在寻找的是:s9.postimage.org/mjkh64h4v/pic.png。谢谢
  • 等一下……我已经为您创建了一个“完整的解决方案”。现在无法上传 - 但你会喜欢的。大约两个小时就可以给它了。我保证,等待是值得的。
  • 刚刚查看了您使用的电子表格的格式。更改列标题以获得您所要求的内容非常简单……我刚刚意识到,如果您开始编辑标题,这些更改将显示为“编辑第 1 行”。我将修改代码以捕获...
  • 谢谢弗洛里斯,我会试一试的。您给我的链接要求我提供登录详细信息,没有这些我无法下载文件。
  • 感谢弗洛里斯,这很有效!还有一个问题,如果我想覆盖更多列中的数据,我需要做什么?目前我有问题、描述、日期。我可以添加更多内容并对其进行监控吗?
猜你喜欢
  • 1970-01-01
  • 2018-03-09
  • 1970-01-01
  • 1970-01-01
  • 2016-06-15
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 2020-01-09
相关资源
最近更新 更多