[英]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? 另外,我猜您在所有工作表中都有
Activate
和Deactivate
事件吗?
You could do it with a single instance of Workbook_SheetActivate
and Workbook_SheetDeactivate
in the ThisWorkbook
module 您可以使用
ThisWorkbook
模块中的单个Workbook_SheetActivate
和Workbook_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
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.
因此,静态变量具有局部变量的范围,但具有模块级变量的生存期。
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
修改一组形状的属性比单独更改它们更有效。
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.