在我的代码中,我使用了一个执行一些文本格式的Workbook_BeforeSave
函数。
当我点击"保存"按钮时,它会运行并格式化某些单元格的大小和字体类型。
这是我的代码的一部分,可以完成这项工作:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim c As Range
Dim rng As Range
Set rng = ActiveSheet.UsedRange.Cells
For Each c In rng
If ispcname(c.Value) = True Or isip(c.Value) = True Then ActiveSheet.Hyperlinks.Add Anchor:=c, Address:="": c.HorizontalAlignment = xlCenter: c = StrConv(c, vbProperCase): c.Font.Name = "Arial": c.Font.Size = "10"
If Right(c, 1) = "$" Then
y = c.Column: x = c.Row
Dim i As Integer
For i = 1 To rng.Rows.Count
If LCase(Cells(i, y).Value) = "backup" Then
If Right(c, 1) = "$" Then Cells(x, y) = Cells(x, y - 2) & "$": ActiveSheet.Hyperlinks.Add Anchor:=c, Address:="": c.Font.Name = "Calibri": c.Font.Size = "10": c.HorizontalAlignment = xlCenter: c.Font.Color = RGB(192, 0, 0)
End If
Next i
End If
Next c
End Sub
我最近实现了一个代码,如果工作簿关闭,它将保存工作簿。
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.DisplayAlerts = False
ActiveWorkbook.Save
Application.DisplayAlerts = True
End Sub
然后出了点问题,我无法解释。当ActiveWorkbook.Save
运行时,应该变成Calibri
的单元格,改为Arial
,大小保持不变,颜色正常工作。但是,当我手动点击保存按钮时,它应该工作。(将单元格更改回Calibri
)
没有其他代码干扰,因为当我注释掉将字体类型更改为Calibri
的部分时,ActiveWorkbook.Save
也停止将其更改为Arial
。
我的问题是:
- 为什么会这样?这是一个错误吗?
- 有什么解决方法吗?
我正在使用 Excel 2007。
根本不知道为什么会发生这种情况,但一种解决方法似乎是手动调用Workbook_BeforeSave
,然后为ActiveWorkbook.Save
调用禁用它:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.DisplayAlerts = False
Application.EnableEvents = False
Workbook_BeforeSave False, False 'Manual call.
Me.Save 'Save without the event firing again.
Application.EnableEvents = True
Application.DisplayAlerts = True
End Sub
也就是说,您在Workbook_BeforeSave
处理程序中也有一些奇怪的逻辑。首先,我不认为For i = 1 To rng.Rows.Count
在做你认为它正在做的事情。它不一定会遍历整个列,因为UsedRange.Cells
不必从第 1 行开始。 如果您使用的范围类似于$A$4:$Z$100
,rng.Rows.Count
将是 97,并且您对Cells(i, y)
的所有引用都将偏离 3。
目前还不清楚ispcname(c.Value) = True Or isip(c.Value) = True
和Right(c, 1) = "$"
是否相互排斥。 如果是,If Right(c, 1) = "$"
实际上应该是一个ElseIf
。
其他几件事:
- 在一行语句中执行 5 个不同的语句
If
是 难以置信地难以阅读,这使得它容易出错。使用实际If...End If
块,除非动作是微不足道的Exit Sub
. - 第二
If Right(c, 1) = "$" Then
总是正确的。 它可以完全删除。 - 实际格式化代码后 一种可读的方式,很明显您正在使用
c
all 的属性 在For Each c In rng
环内的地方。 我会把它放在一个With
块。 - 您只需要使用一次
ActiveSheet
。 然后 您可以从rng.Parent
获得它,或者(更好)获得 引用它。 - 养成使用
String
退货的习惯 函数而不是在需要时Variant
返回函数String
. J.F.Right$
而不是Right
- 后者执行 隐式演员表。 - 完全限定您对
Cells
的所有引用。 - 避免隐式使用对象的默认属性,即
Range.Value
. - 对行计数器使用
Long
,而不是Integer
以避免溢出的可能性。 - 使用
vbNullString
而不是文字""
。 Font.Size
以点为单位。 它应该是一个数字,而不是一个字符串。
它应该看起来更像这样:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim c As Range
Dim sh As Worksheet
Set sh = ActiveSheet 'Tip 4
Dim rng As Range
Set rng = sh.UsedRange.Cells
For Each c In rng
With c 'Tip 3
If ispcname(.Value) Or isip(.Value) Then 'Tip 1
sh.Hyperlinks.Add Anchor:=c, Address:=vbNullString 'Tips 4 and 9
.HorizontalAlignment = xlCenter
.Value = StrConv(.Value, vbProperCase) 'Tip 7
.Font.Name = "Arial"
.Font.Size = 10 'Tip 10
End If 'Pretty sure this should be an ElseIf structure here.
If Right$(.Value, 1) = "$" Then 'Tips 5 and 7.
y = .Column
x = .Row
Dim i As Long 'Tip 8
For i = 1 To rng.Rows.Count 'This is most likely wrong.
'Tip 2 used to be here.
If LCase$(sh.Cells(i, y).Value) = "backup" Then 'Tips 1, 5, and 6
.Value = sh.Cells(x, y - 2).Value & "$" 'Tips 4, 6, and 7
sh.Hyperlinks.Add Anchor:=c, Address:=vbNullString 'Tips 4 and 9
.Font.Name = "Calibri"
.Font.Size = 10 'Tip 10
.HorizontalAlignment = xlCenter
.Font.Color = RGB(192, 0, 0)
End If
Next i
End If
End With
Next c
End Sub
如果使用"$"表示单元格是货币,请不要测试最后一个字符是否为"$"。 您必须检查单元格是否具有货币格式。
修改行
if right(c,1)= "$"
自
fc = c.NumberFormat
If InStr(1, c, "$") = 0 Then ...
您的测试永远不会在 C 中找到"$"。