excel - 如果更新了其中一个工作表中的列,则更新多列
excel - Update multiple columns if a column from one of the worksheet is updated
我有多个 sheet,所有 sheet 中的其中一列包含相同的列(比如 "Names")。在每一列 "Names" 中都有对应的 "Status" 列。每个 "Names" 列可能包含来自一个或多个 sheet 的相同记录。如果 "Status" 列中的一条记录被更新,我想得到它对应的 "Names" 列值,然后搜索所有 sheet s,如果它也有相同的 "Names" 记录,我应该能够根据第一个 "Status" 更新的值更新其相应的 "Status" 值。
现在,我能够从网上搜索有效的答案(见下文),问题是它只能以一种方式起作用。我可以从 sheet(比如 sheet1)更新一个值,它也可以从一个或多个作品 sheet 更新一个值。但是当我尝试更新另一个作品sheet(不是sheet1)的值时,它returns 出现错误Method "Find' of object 'Range' failed
。
示例(这应该在每个作品中sheet,带有列,sheet 名称已更改):
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
Dim fn2 As Range
If Not Intersect(Target, Range("B:B")) Is Nothing Then
Set fn2 = Sheets("Sheet1").Range("D:D").Find(Target.Offset(, -11).Value, , xlValues, xlWhole)
If Not fn2 Is Nothing Then
fn2.Offset(, 13) = Target.Value
MsgBox "A record has been updated name_tab tab"
End If
End If
End Sub
请帮忙。谢谢
您的代码错误是因为您试图偏移 D 列左侧的 11 列
编辑 在 OP 澄清后:
to-be-searched-in sheet 要硬编码的名称,因为找不到通用模式来在所有其他工作中过滤它们sheets
Names
和 Status
列相应地在每个 [=26 的第 1 行中有 "Names" 和 "Status" headers =]to-be-searched-in工作sheet
edited2 以考虑第一个更新行索引(参见带“****”的行)
将此代码放入 ThisWorkbook
代码窗格:
Option Explicit
Const STATUSHEADER As String = "Status"
Const NAMESHEADER As String = "Names"
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim nameValue As String
Dim sht As Worksheet
Dim sheetNames As Variant
Dim firstUpdatedRowIndex As Long '<--| this will store first updated row index ****
If Not Proceed(Target) Then Exit Sub
sheetNames = Array("Sheet0001", "Sheet0002", "Sheet0003") '<--| fill array with sheets-to-be-searched names
On Error GoTo EXITSUB
Application.EnableEvents = False
nameValue = GetNameValue(Target) '<--| get value in the "Names" column corresponding row
For Each sht In Worksheets(sheetNames) '<--| loop through to-be-searched-in sheets
If sht.name <> Sh.name Then UpdateSheet sht, nameValue, Target.value, firstUpdatedRowIndex '****
Next sht
EXITSUB:
Application.EnableEvents = True
End Sub
Sub UpdateSheet(sht As Worksheet, nameValue As String, statusValue As Variant, firstUpdatedRowIndex As Long) '****
Dim namesCol As Long, statusCol As Long
Dim f As Range
With sht '<--| refer to current to-be-searched-in sheet
With .Rows(1).SpecialCells(XlCellType.xlCellTypeConstants) '<--| refer to its 1st row non blank cells range
namesCol = FindFirstCell(NAMESHEADER, .Cells).Column '<--| get its "Names" column index
statusCol = FindFirstCell(STATUSHEADER, .Cells).Column '<--| get its "Status" column index
End With
Set f = FindFirstCell(nameValue, .Columns(namesCol).SpecialCells(XlCellType.xlCellTypeConstants)) '<--| search its "names" column for the "name" value corresponding to the changed "Status" in the originally changed sheet
If Not f Is Nothing Then '<--| if any matching cell found in "Names" column ...
.Cells(f.row, statusCol) = statusValue '<--| update its corresponding "Status" column value
MsgBox "record in row " & f.row & " has been updated in " & .name & " tab"
If firstUpdatedRowIndex = 0 Then firstUpdatedRowIndex = f.row '<--| store first updated row ****
End If
End With
End Sub
Function FindFirstCell(value As String, rng As Range) As Range
Set FindFirstCell = rng.Find(what:=value, lookat:=xlWhole, LookIn:=xlValues, MatchCase:=True)
End Function
Function GetNameValue(Target As Range) As String
With Target.Parent
GetNameValue = .Cells(Target.row, FindFirstCell(NAMESHEADER, .Range(.Cells(1, 1), .Cells(1, Target.Column - 1))).Column).value '<--| search columns preceeding the 'Target' (i.e.: "Status") one for the "Names" column and get its value at the row corresponding to changed "Status" one
End With
End Function
Function Proceed(rng As Range) As Boolean
Proceed = rng.Cells.Count = 1 '<--| proceed if only one changed cell
If Proceed Then Proceed = rng.Offset(-rng.row + 1) = STATUSHEADER '<--| proceed only if the changed cell is a "Status" column
End Function
我有多个 sheet,所有 sheet 中的其中一列包含相同的列(比如 "Names")。在每一列 "Names" 中都有对应的 "Status" 列。每个 "Names" 列可能包含来自一个或多个 sheet 的相同记录。如果 "Status" 列中的一条记录被更新,我想得到它对应的 "Names" 列值,然后搜索所有 sheet s,如果它也有相同的 "Names" 记录,我应该能够根据第一个 "Status" 更新的值更新其相应的 "Status" 值。
现在,我能够从网上搜索有效的答案(见下文),问题是它只能以一种方式起作用。我可以从 sheet(比如 sheet1)更新一个值,它也可以从一个或多个作品 sheet 更新一个值。但是当我尝试更新另一个作品sheet(不是sheet1)的值时,它returns 出现错误Method "Find' of object 'Range' failed
。
示例(这应该在每个作品中sheet,带有列,sheet 名称已更改):
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
Dim fn2 As Range
If Not Intersect(Target, Range("B:B")) Is Nothing Then
Set fn2 = Sheets("Sheet1").Range("D:D").Find(Target.Offset(, -11).Value, , xlValues, xlWhole)
If Not fn2 Is Nothing Then
fn2.Offset(, 13) = Target.Value
MsgBox "A record has been updated name_tab tab"
End If
End If
End Sub
请帮忙。谢谢
您的代码错误是因为您试图偏移 D 列左侧的 11 列
编辑 在 OP 澄清后:
to-be-searched-in sheet 要硬编码的名称,因为找不到通用模式来在所有其他工作中过滤它们sheets
Names
和Status
列相应地在每个 [=26 的第 1 行中有 "Names" 和 "Status" headers =]to-be-searched-in工作sheet
edited2 以考虑第一个更新行索引(参见带“****”的行)
将此代码放入 ThisWorkbook
代码窗格:
Option Explicit
Const STATUSHEADER As String = "Status"
Const NAMESHEADER As String = "Names"
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim nameValue As String
Dim sht As Worksheet
Dim sheetNames As Variant
Dim firstUpdatedRowIndex As Long '<--| this will store first updated row index ****
If Not Proceed(Target) Then Exit Sub
sheetNames = Array("Sheet0001", "Sheet0002", "Sheet0003") '<--| fill array with sheets-to-be-searched names
On Error GoTo EXITSUB
Application.EnableEvents = False
nameValue = GetNameValue(Target) '<--| get value in the "Names" column corresponding row
For Each sht In Worksheets(sheetNames) '<--| loop through to-be-searched-in sheets
If sht.name <> Sh.name Then UpdateSheet sht, nameValue, Target.value, firstUpdatedRowIndex '****
Next sht
EXITSUB:
Application.EnableEvents = True
End Sub
Sub UpdateSheet(sht As Worksheet, nameValue As String, statusValue As Variant, firstUpdatedRowIndex As Long) '****
Dim namesCol As Long, statusCol As Long
Dim f As Range
With sht '<--| refer to current to-be-searched-in sheet
With .Rows(1).SpecialCells(XlCellType.xlCellTypeConstants) '<--| refer to its 1st row non blank cells range
namesCol = FindFirstCell(NAMESHEADER, .Cells).Column '<--| get its "Names" column index
statusCol = FindFirstCell(STATUSHEADER, .Cells).Column '<--| get its "Status" column index
End With
Set f = FindFirstCell(nameValue, .Columns(namesCol).SpecialCells(XlCellType.xlCellTypeConstants)) '<--| search its "names" column for the "name" value corresponding to the changed "Status" in the originally changed sheet
If Not f Is Nothing Then '<--| if any matching cell found in "Names" column ...
.Cells(f.row, statusCol) = statusValue '<--| update its corresponding "Status" column value
MsgBox "record in row " & f.row & " has been updated in " & .name & " tab"
If firstUpdatedRowIndex = 0 Then firstUpdatedRowIndex = f.row '<--| store first updated row ****
End If
End With
End Sub
Function FindFirstCell(value As String, rng As Range) As Range
Set FindFirstCell = rng.Find(what:=value, lookat:=xlWhole, LookIn:=xlValues, MatchCase:=True)
End Function
Function GetNameValue(Target As Range) As String
With Target.Parent
GetNameValue = .Cells(Target.row, FindFirstCell(NAMESHEADER, .Range(.Cells(1, 1), .Cells(1, Target.Column - 1))).Column).value '<--| search columns preceeding the 'Target' (i.e.: "Status") one for the "Names" column and get its value at the row corresponding to changed "Status" one
End With
End Function
Function Proceed(rng As Range) As Boolean
Proceed = rng.Cells.Count = 1 '<--| proceed if only one changed cell
If Proceed Then Proceed = rng.Offset(-rng.row + 1) = STATUSHEADER '<--| proceed only if the changed cell is a "Status" column
End Function