我正在尝试在excel工作表中创建自定义属性,然后检索其值。当我不使用空字符串,即""
时,这很好。当我使用空字符串时,我收到此错误:
Run-time error '7':
Out of memory
这是我正在使用的代码:
Sub proptest()
Dim cprop As CustomProperty
Dim sht As Worksheet
Set sht = ThisWorkbook.Sheets("control")
sht.CustomProperties.Add "path", ""
For Each cprop In ThisWorkbook.Sheets("control").CustomProperties
If cprop.Name = "path" Then
Debug.Print cprop.Value
End If
Next
End Sub
代码在Debug.Print cprop.value
处失败。我不应该最初能够将属性设置为""
吗?
答案 0 :(得分:1)
使用 vbNullChar 可以使用,示例:
Sub proptest()
Dim sht As Worksheet
Set sht = ThisWorkbook.Sheets("control")
' On Error Resume Next
sht.CustomProperties.Item(1).Delete
' On Error GoTo 0
Dim pathValue As Variant
pathValue = vbNullChar
Dim pathCustomProperty As CustomProperty
Set pathCustomProperty = sht.CustomProperties.Add("path", pathValue)
Dim cprop As CustomProperty
For Each cprop In ThisWorkbook.Sheets("control").CustomProperties
If cprop.Name = "path" Then
Debug.Print cprop.Value
End If
Next
End Sub
答案 1 :(得分:1)
我认为丹尼尔·杜塞克的评论和答案显然无法做到这一点。该属性应至少有1个字符有效,空字符串不允许,并且在调用.Value时会出错。
因此,当您没有为其分配实际值时,Add
此属性的长度为1或更多string
并且您Delete
属性。
答案 2 :(得分:0)
如前所述,无法设置空字符串。
一个简单的解决方法是使用一个神奇的单词或字符,例如~Empty
(或任何足以证明您的能力的东西):
Dim MyProperty As Excel.CustomProperty = ...
Dim PropertyValue As String = If(MyProperty.Value = "~Empty", String.Empty, MyPropertyValue)
一种稍微昂贵一点的解决方法,但100%安全是使用一个字符开始的自定义属性的所有值,然后始终将其删除。访问该值时,系统地删除第一个字符:
Dim MyProperty As Excel.CustomProperty = ...
Dim PropertyValue As String = Strings.Mid(MyProperty.Value, 2)
您可以编写一个扩展名以使您的生活更轻松:
<System.Runtime.CompilerServices.Extension>
Function ValueTrim(MyProperty as Excel.CustomProperty) As String
Return Strings.Mid(MyProperty.Value, 2)
End Function
现在您可以像这样使用它:Dim MyValue As String = MyProperty.ValueTrim
添加自定义属性时,请遵循相反的原则:
<System.Runtime.CompilerServices.Extension>
Function AddTrim(MyProperties As Excel.CustomProperties, Name As String, Value As String) as Excel.CustomProperty
Dim ModifiedValue As String = String.Concat("~", Value) 'Use ~ or whatever character you lie / Note Strig.Concat is the least expensive way to join two strings together.
Dim NewProperty As Excel.CustomProperty = MyProperties.Add(Name, ModifiedValue)
Return NewProperty
End Function
要像这样使用:MyProperties.AddTrim(Name, Value)
希望这可以帮助遇到此问题的其他人。
答案 3 :(得分:0)
根据其他答案和一些反复试验,我编写了一个类来包装 Worksheet.CustomProperty
。
设置和获取 Worksheet.CustomProperty
的值并测试 Worksheet
是否具有 CustomProperty
VERSION 1.0 CLASS
Attribute VB_Name = "WorksheetProperty"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
'@Folder("Classes")
'@PredeclaredId
Option Explicit
Private Type TMembers
Name As String
Worksheet As Worksheet
End Type
Private this As TMembers
Public Property Get Create(pWorksheet As Worksheet, pName As String) As WorksheetProperty
With New WorksheetProperty
Set .Worksheet = pWorksheet
.Name = pName
Set Create = .Self
End With
End Property
Public Property Get Self() As WorksheetProperty
Set Self = Me
End Property
Public Property Get Worksheet() As Worksheet
Set Worksheet = this.Worksheet
End Property
Public Property Set Worksheet(ByVal pValue As Worksheet)
Set this.Worksheet = pValue
End Property
Public Property Get Name() As String
Name = this.Name
End Property
Public Property Let Name(ByVal pValue As String)
this.Name = pValue
End Property
Public Property Get Value() As String
Dim P As CustomProperty
For Each P In Worksheet.CustomProperties
If P.Name = Name Then
Value = P.Value
Exit Property
End If
Next
End Property
Public Property Let Value(ByVal pValue As String)
Delete
Worksheet.CustomProperties.Add Name:=Name, Value:=pValue
End Property
Public Property Get hasCustomProperty(pWorksheet As Worksheet, pName As String) As Boolean
Dim P As CustomProperty
For Each P In pWorksheet.CustomProperties
If P.Name = pName Then
hasCustomProperty = True
Exit Property
End If
Next
End Property
Public Sub Delete()
Dim P As CustomProperty
For Each P In Worksheet.CustomProperties
If P.Name = Name Then
P.Delete
Exit For
End If
Next
End Sub
我的自定义 Unit 类有几个属性返回一个 WorksheetProperty。它使我的数据库与我的工作表同步变得非常容易。
Public Function hasMeta(Ws As Worksheet) As Boolean
hasMeta = WorksheetProperty.hasCustomProperty(Ws, MetaName)
End Function
Public Property Get Id() As WorksheetProperty
Set Id = WorksheetProperty.Create(this.Worksheet, "id")
End Property
Public Property Get CourseID() As WorksheetProperty
Set CourseID = WorksheetProperty.Create(this.Worksheet, "course_id")
End Property
Public Property Get Name() As WorksheetProperty
Set Name = WorksheetProperty.Create(this.Worksheet, "unit_name")
End Property
'ActiveSheet has a CustomProperty
Debug.Print WorksheetProperty.hasCustomProperty(ActiveSheet, "LastDateSynced")
'Set a CustomProperty
WorksheetProperty.Create(ActiveSheet, "LastDateSynced").Value = Now
'Retrieve a CustomProperty
Debug.Print WorksheetProperty.Create(ActiveSheet, "LastDateSynced").Value