以编程方式在Excel中选择其他工作表先例或依赖项

Mar*_*urd 6 excel vba excel-vba

在Excel Ctrl+中[]有时会直接切换到另一个工作表以显示该工作表中的先例或从属项.

我想以编程方式进行编程,因为我想获得一系列单元格的先例(或依赖项).

Range.DependentsRange.Precedents其他问题,但解决方案没有解决额外的问题.

小智 6

马克做了一些不错的工作,但是这个宏完全不会在同一张纸上出现'凹陷而失败,当有来自多张纸的凹痕时,因为无法从多个单张纸单元创建选择.

我个人需要所有这些功能来替换"Ctrl + ["和"Ctrl +]"快捷方式功能,以跳转到先例和家属.不幸的是,这些快捷方式在国际键盘上完全无法使用,其中这些方括号隐藏在AltGr(右Alt)组合下,Excel不允许Ctrl + AltGr + 8和Ctrl + AltGr + 8给出相同的结果,并且还有无法重新映射默认快捷方式.

所以我稍微改进了Mark的代码以修复这些问题并从代码中删除弹出消息,因为我应该知道自己是否无法选择所有'凹痕,但我希望函数能够顺利运行而不必单击OK all时间.因此,该函数只是跳转到工作表中,该工作表首先在公式中链接.

我希望这对其他人也有用.

仍然困扰我的唯一事情是,当Application.ScreenUpdating = False Avoids跳过工作表和工作簿时,箭头仍然保持闪烁.有什么办法可以避免这个吗

Option Explicit

Private Sub GetOffSheetDents(ByVal doPrecedents As Boolean)
'Main function, calling for separate function to find links to all cells to one of the input cells. Works for finding precedents for a whole selection (group of cells)
'doPrecedents is TRUE, if we are searching for precedents and FALSE, if looking for dependents
Dim InputCell As Range
Dim results As Range
Dim r As Range
Dim sheet As Worksheet

Application.ScreenUpdating = False

For Each InputCell In Application.Intersect(ActiveSheet.UsedRange, Selection)
'Cycle to go over all initially selected cells. If only one cell selected, then happens only once.
    Set r = oneCellDependents(InputCell, doPrecedents)
    ' r is resulting cells from each iteration of input cell to the function.
    If Not r Is Nothing Then      'if there were precedents/dependents
        If sheet Is Nothing Then  'if this is the first time.
            Set sheet = r.Worksheet
            Include results, r
        ElseIf Not sheet Is r.Worksheet Then 'if new precedent/dependent is on another worksheet, don't add to selection (gets lost)
        Else
            Include results, r
        End If
    End If
Next
Application.ScreenUpdating = True

If results Is Nothing Then
    Beep
Else
    results.Worksheet.Activate
    results.Select
End If
End Sub

Sub GetOffSheetDependents()
'Function defines, if we are looking for Dependents (False) or Precedents (True)
GetOffSheetDents False

End Sub

Sub GetOffSheetPrecedents()
'Function defines, if we are looking for Dependents (False) or Precedents (True)
GetOffSheetDents True

End Sub

Private Function Include(ByRef ToUnion As Range, ByVal Value As Range) As Range
If ToUnion Is Nothing Then
    Set ToUnion = Value
    ElseIf Value.Worksheet Is ToUnion.Worksheet Then 'if new precedent/dependent is on the same worksheet, then add to selection
            'if new precedent/dependent is on another worksheet, don't add to selection (gets lost)
        Set ToUnion = Application.Union(ToUnion, Value)
End If
Set Include = ToUnion
End Function

Private Function oneCellDependents(ByVal inRange As Range, Optional doPrecedents As Boolean) As Range
'Function finds dependents for one of the selected cells. Happens only once, if initially only one cell selected.
Dim inAddress As String, returnSelection As Range
Dim i As Long, pCount As Long, qCount As Long
Application.ScreenUpdating = False
If inRange.Cells.Count <> 1 Then Error.Raise 13 'seems to check, that only one cell is handled, but does not seem to be necessary step.

'remember selection
Set returnSelection = Selection ' to keep initial selection for GetOffSheetDents function.
inAddress = fullAddress(inRange) ' takes address of starting cell what is analyzed.
pCount = 1

With inRange   'all functions apply to this initial cell.
    .ShowPrecedents
    .ShowDependents
    .NavigateArrow doPrecedents, 1 ' go to first precedent (if first argument is true)/dependent. But why required?
    Do Until fullAddress(ActiveCell) = inAddress
        .NavigateArrow doPrecedents, pCount 'go to first precedent, then second etc.
        If ActiveSheet.Name <> returnSelection.Parent.Name Then ' checks, if the precedent is NOT on the same sheet

            Do
                qCount = qCount + 1   'qCount follows external references, if arrow is external reference arrow.
                .NavigateArrow doPrecedents, pCount, qCount 'go to first exteranl precedent, then second etc.
                Include oneCellDependents, Selection
                On Error Resume Next
                .NavigateArrow doPrecedents, pCount, qCount + 1 'could remove this step and check for error before Include?
                If Err.Number <> 0 Then Exit Do
                On Error GoTo 0  ' not sure if this is used, since if there is error, then already Exit Do in previous step.
            Loop
            On Error GoTo 0 'not sure, if necessary, since just asked in loop.
        Else  ' if precedent IS ON the same sheet.
            Include oneCellDependents, Selection
        End If
        pCount = pCount + 1
        .NavigateArrow doPrecedents, pCount
    Loop
    .Parent.ClearArrows
End With

'return selection to where it was
With returnSelection
    .Parent.Activate
    .Select
End With

End Function

Private Function fullAddress(inRange As Range) As String
'Function takes a full address with sheet name

With inRange
    fullAddress = .Parent.Name & "!" & .Address
End With
End Function
Run Code Online (Sandbox Code Playgroud)


Mar*_*urd 3

经过一番谷歌搜索后,我发现这个问题在2003 年就得到了解决。

但我使用了这里的代码。

问题在于DependentsPrecedentsRange属性,不能引用多个工作表。

该解决方案用于NavigateArrow定位跨板“凹痕”。

这是我的代码:

Option Explicit

Private Sub GetOffSheetDents(ByVal doPrecedents As Boolean)

Dim c As Range
Dim results As Range
Dim r As Range
Dim sheet As Worksheet
Dim extra As Boolean

For Each c In Application.Intersect(ActiveSheet.UsedRange, Selection)
    Set r = oneCellDependents(c, doPrecedents)
    If Not r Is Nothing Then
        If r.Worksheet Is ActiveSheet Then
            ' skip it
        ElseIf sheet Is Nothing Then
            Set sheet = r.Worksheet
            Include results, r
        ElseIf Not sheet Is r.Worksheet Then
            If Not extra Then
                extra = True
                MsgBox "More than one external sheet in " & IIf(doPrecedents, "Precedents", "Dependents") & ". Only displaying first sheet."
            End If
        Else
            Include results, r
        End If
    End If
Next

If results Is Nothing Then
    Beep
Else
    results.Worksheet.Activate
    results.Select
End If
End Sub

Sub GetOffSheetDependents()

GetOffSheetDents False

End Sub

Sub GetOffSheetPrecedents()

GetOffSheetDents True

End Sub

Private Function Include(ByRef ToUnion As Range, ByVal Value As Range) As Range
If ToUnion Is Nothing Then
    Set ToUnion = Value
Else
    Set ToUnion = Application.Union(ToUnion, Value)
End If
Set Include = ToUnion
End Function

Private Function oneCellDependents(ByVal inRange As Range, Optional doPrecedents As Boolean) As Range

Dim inAddress As String, returnSelection As Range
Dim i As Long, pCount As Long, qCount As Long

If inRange.Cells.Count <> 1 Then Error.Raise 13

Rem remember selection
Set returnSelection = Selection
inAddress = fullAddress(inRange)

Application.ScreenUpdating = False
With inRange
    .ShowPrecedents
    .ShowDependents
    .NavigateArrow doPrecedents, 1
    Do Until fullAddress(ActiveCell) = inAddress
        pCount = pCount + 1
        .NavigateArrow doPrecedents, pCount
        If ActiveSheet.Name <> returnSelection.Parent.Name Then

            Do
                qCount = qCount + 1
                .NavigateArrow doPrecedents, pCount, qCount
                Include oneCellDependents, Selection
                On Error Resume Next
                .NavigateArrow doPrecedents, pCount, qCount + 1
                If Err.Number <> 0 Then _
                    Exit Do
                On Error GoTo 0
            Loop
            On Error GoTo 0
            .NavigateArrow doPrecedents, pCount + 1
        Else
            Include oneCellDependents, Selection
            .NavigateArrow doPrecedents, pCount + 1
        End If
    Loop
    .Parent.ClearArrows
End With

Rem return selection to where it was
With returnSelection
    .Parent.Activate
    .Select
End With
Application.ScreenUpdating = True

End Function

Private Function fullAddress(inRange As Range) As String
With inRange
    fullAddress = .Parent.Name & "!" & .Address
End With
End Function
Run Code Online (Sandbox Code Playgroud)