简体   繁体   English

将形状从上一个工作表移动到当前工作表

[英]moving shape from previous worksheet to current worksheet

I have a grouping of 20 chevron shapes, used to identify how far into the spreadsheet you are. 我有20个人字形形状的分组,用于标识您到电子表格的距离。 Users start on tab 1 the first chevron is coloured, and continue along. 用户从选项卡1开始,第一个人字形为彩色,然后继续。 On tab 15, 15 chevrons are coloured, and on tab 20, all 20 chevrons are coloured. 在选项卡15上,为15个V形燕尾形上色,在选项卡20上,所有20个V形燕尾形上色。

I have tried identifying the previous active worksheet, but I constantly get errors. 我曾尝试标识以前的活动工作表,但是却不断出错。 Users can jump from tab 1 to 5 to 10, or from tab 20, to 5 to 13. As a result, I cannot use the .previous command. 用户可以从选项卡1跳到5到10,或者从选项卡20跳到5到13。结果,我不能使用.previous命令。 I have tried using a global variable in lieu with the worksheet deactivate to get the lastWS name, as I feel this is the best method, but to no avail. 我尝试使用全局变量代替停用工作表来获取lastWS名称,因为我认为这是最好的方法,但无济于事。 IE this is my global variable IE浏览器,这是我的全局变量

Public lastWS As Worksheet

To change chevron colours, which works fine, I call when the worksheet is activated 要更改人字形颜色,效果很好,我在工作表激活时打电话给我

Private Sub Worksheet_Activate()
  Call chevronColours(1)
End Sub

on each worksheet I have this to recognize the last used worksheet: 在每个工作表上,我都有这个来识别上次使用的工作表:

Private Sub Worksheet_DeActivate()
  Set lastWS = ActiveSheet
End Sub

and my module code is: 我的模块代码是:

Sub chevronColours(k As Integer)

Dim r As Integer, g As Integer, b As Integer, i As Integer
Set wbk = ThisWorkbook
Set currentWS = ActiveSheet
lastWS.Shapes("Group 2").Cut
wbk.ActiveSheet.Range("B2").Select
wbk.ActiveSheet.Paste

For i = 1 To 19
  If i <= k Then
    currentWS.Shapes("Chevron " & i).Fill.ForeColor.RGB = RGB(0, 255, 0)
  Else
    currentWS.Shapes("Chevron " & i).Fill.ForeColor.RGB = RGB(255, 255, 255)
  End If
Next i

End Sub

In this scenario it says that the item with the specified name was not found. 在这种情况下,它表明找不到具有指定名称的项目。 Using the debugger I found this to be because when using the deactivate procedure, my lastWS become the current worksheet. 使用调试器,我发现这是因为使用取消激活过程时,我的lastWS成为当前工作表。

What can I do to use the previous worksheet in this way? 我该怎么做才能以这种方式使用上一个工作表?

Rather than Set lastWS = ActiveSheet use Set lastWS = Me . 而不是Set lastWS = ActiveSheet而是使用Set lastWS = Me

Also, I guess you have the Activate and Deactivate events in all workssheets? 另外,我猜您在所有工作表中都有ActivateDeactivate事件吗?

You could do it with a single instance of Workbook_SheetActivate and Workbook_SheetDeactivate in the ThisWorkbook module 您可以使用ThisWorkbook模块中的单个Workbook_SheetActivateWorkbook_SheetDeactivate实例来完成此操作

Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
    Set lastWS = Sh
End Sub

Also, your chevronColours Sub could be passed the workbook, like this 另外,您的chevronColours Sub可以像这样通过工作簿

Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    chevronColours Sh
End Sub

and defined as 并定义为

Sub chevronColours(currentWS As Worksheet)

I think you will find there are a few other issues with your chevronColours code. 我想您会发现chevronColours代码还有其他一些问题。 Here's your code refactored 这是重构的代码

Sub chevronColours(currentWS As Worksheet)
    Dim k As Long, i As Long
    Dim rng As Range
    Dim shp As Shape
    Dim g As GroupObject

    Application.ScreenUpdating = False
    Set rng = Selection
    lastWS.Shapes("Group 2").Cut
    currentWS.Paste
    Set g = Selection
    rng.Select
    g.Name = "Group 2"
    With currentWS.Range("B2")
        g.Top = .Top
        g.Left = .Left
    End With
    k = currentWS.Index
    If g.ShapeRange.GroupItems.Count = currentWS.Parent.Worksheets.Count Then
        For i = 1 To g.ShapeRange.GroupItems.Count
            g.ShapeRange.GroupItems(i).Fill.ForeColor.RGB = IIf(i <= k, vbGreen, vbWhite)
        Next i
    Else
        ' Sheets vs chevron count mismatch
        '  what now?
    End If
    Application.ScreenUpdating = True
End Sub

Storing References to the Worksheets 存储对工作表的引用

What I did was use Static ChevronList As Object reference an ArrayList. 我所做的是使用Static ChevronList As Object引用ArrayList。 The worksheet names are added to the ArrayList. 工作表名称将添加到ArrayList。 ArrayList.IndexOf_3(Worksheet.Name) returns the zero based Index of the worksheet name. ArrayList.IndexOf_3(Worksheet.Name)返回工作表名称的从零开始的索引。

Better Soulutions - Static Variables 更好的解决方案-静态变量

Variables do have a lifetime. 变量确实有生命周期。 Indicates that the local variable is preserved between calls. 指示在两次调用之间保留局部变量。 A static variable can be thought of as a local variable with memory. 可以将静态变量视为具有内存的局部变量。 A static variable is a local variable whose lifetime is the lifetime of the entire module and not the procedure where it is declared. 静态变量是一个局部变量,其生存期是整个模块的生存期,而不是声明它的过程。 In fact static variables retain their values as long as the code module is active. 实际上,只要代码模块处于活动状态,静态变量就会保留其值。 There does not have to be any code running all the time. 不必一直运行任何代码。 Therefore a static variable has the scope of a local variable but the lifetime of a module level variable. 因此,静态变量具有局部变量的范围,但具有模块级变量的生存期。

Working with Shapes 处理形状

You should give the group a meaningful name. 您应该给该组取一个有意义的名称。

  ActiveSheet.Shapes("Group 2").Name = "Chevron Group" 

Passing an array on names to the Shapes.Range() property returns a ShapeRange of of all the shapes in the array. 将名称数组传递给Shapes.Range()属性将返回数组中所有形状的ShapeRange Using the ShapeRange to modify the properties of a group of shapes is more efficient then changing them individually. 使用ShapeRange修改一组形状的属性比单独更改它们更有效。

Workbook Events 工作簿活动

As Chris Neilsen mentioned use the Workbook_SheetActivate instead of the Worksheet_Activate events of the individual worksheets. 正如Chris Neilsen提到的那样,请使用Workbook_SheetActivate而不是各个工作表的Worksheet_Activate事件。 I recommend also recommend calling the subroutine from the Workbook_Open event. 我建议还建议从Workbook_Open事件中调用该子例程。 The Workbook_Open fires after the user has enabled the content. 用户启用内容后,将触发Workbook_Open If the user opens the workbook, changes worksheets, and then enables the content 如果用户打开工作簿,更改工作表,然后启用内容

 Private Sub Workbook_Open() MoveChevronGroup ActiveSheet.Range("B2") End Sub 

在此处输入图片说明


I didn't bother using the last worksheet to track the location of the group. 我没有费心使用上一个工作表来跟踪组的位置。 Searching 20 sheets for the group is virtually instantaneous and will prevent possible bugs. 在该组中搜索20张纸实际上是瞬时的,可以防止可能的错误。


在此处输入图片说明

Option Explicit
Const DebugMode = True

Private Sub Workbook_Open()
    MoveChevronGroup ActiveSheet.Range("B2")
End Sub

Private Sub Workbook_SheetActivate(ByVal sh As Object)
    Application.ScreenUpdating = False
    MoveChevronGroup sh.Range("B2")
    Application.ScreenUpdating = True
End Sub

Private Sub MoveChevronGroup(Optional Destination As Range)
    Const GroupName As String = "Chevron Group"
    Static ChevronList As Object
    Dim ChevronGroup As Shape, ws As Worksheet
    Dim results() As Variant
    Dim ChevronCount As Long, n As Long
    If ChevronList Is Nothing Then Set ChevronList = CreateObject("System.Collections.ArrayList")

    For Each ws In ThisWorkbook.Worksheets
        On Error Resume Next
        Set ChevronGroup = ws.Shapes(GroupName)
        On Error GoTo 0
        If Not ChevronGroup Is Nothing Then Exit For
    Next

    Set ws = Destination.Parent

    If Not ChevronGroup.Parent.Name = ws.Name Then
        ChevronGroup.Cut
        Destination.Parent.Paste
        Set ChevronGroup = ws.Shapes(GroupName)
        ChevronGroup.Left = Destination.Left
        ChevronGroup.Top = Destination.Top
    End If

    If Not ChevronList.Contains(ws.Name) Then ChevronList.Add ws.Name
    ChevronCount = ChevronList.IndexOf_3(ws.Name) + 1

    If DebugMode Then Debug.Print "ChevronList.Count: "; ChevronList.Count, "ChevronList.IndexOf_3(ws.Name) + 1: "; ChevronList.IndexOf_3(ws.Name) + 1

    ReDim results(ChevronCount - 1)
    For n = 1 To ChevronCount
        results(n - 1) = n
    Next

    If DebugMode Then Debug.Print "Results Array Values: "; Join(results, ",")

    ChevronGroup.Fill.ForeColor.RGB = RGB(255, 255, 255)
    ChevronGroup.GroupItems.Range(results).Fill.ForeColor.RGB = RGB(0, 255, 0)
End Sub

Modified code to add the Shape Index instead of the Shape Name to the results(). 修改后的代码以将Shape Index而不是Shape Name添加到results()中。 There seems to be a bug using the shape names. 使用形状名称似乎存在错误。 I am going to ask SO about the bug. 我要问这个错误。 Because of the change the Chevroons need to be added to the group in order. 由于更改,需要将雪佛龙按顺序添加到组中。

Download Chevrons Demo.xlsm . 下载Chevrons Demo.xlsm The main code is in the Workbook's code module. 主要代码在工作簿的代码模块中。 The code for prepping the workbook, adding sheets and Chevrons, are in the PrepWorkbook module. 准备工作簿,添加工作表和人PrepWorkbook的代码在PrepWorkbook模块中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM