您有哪些打高尔夫球的一般秘诀VBA
?我正在寻找可以应用于编码高尔夫问题的想法,这些想法至少在某些方面是特定的VBA
(例如,“删除评论”不是答案)。请为每个答案发布一个提示。
当我使用其他语言时,我的能力最强VBA
,而且VBA
在这个网站上我看不到有很多高尔夫球手在使用。
您有哪些打高尔夫球的一般秘诀VBA
?我正在寻找可以应用于编码高尔夫问题的想法,这些想法至少在某些方面是特定的VBA
(例如,“删除评论”不是答案)。请为每个答案发布一个提示。
当我使用其他语言时,我的能力最强VBA
,而且VBA
在这个网站上我看不到有很多高尔夫球手在使用。
Answers:
ByRef
调用潜艇时利用默认设置有时可以使用Sub
呼叫代替a Function
来保存一些其他字符...
这(87个字符)
Sub a()
b = 0
Do Until b = 5
b = c(b)
Loop
End Sub
Function c(d)
c = d + 1
End Function
可以重新制作为(73个字符):
Sub a()
b = 0
Do Until b = 5
c b
Loop
End Sub
Sub c(d)
d = d + 1
End Sub
请注意,尽管您永远不会重新分配的值,但这不会永远循环b
。
上面的代码不使用Function
调用,而是利用了调用的ByRef
“按引用”功能Sub
。这意味着传递的参数与调用函数中的变量相同(而不是ByVal
传递“按值”,它是一个副本)。对传递的变量的任何修改都将转换回调用函数。
默认情况下,vba将所有参数都用作ByRef
,因此不需要用完字符来定义它。
上面的示例可能无法完全为您翻译,具体取决于函数的返回值。(即返回与传递的数据类型不同的数据类型),但这也允许在仍修改原始变量的同时获得返回值的可能性。
例如:
Sub a()
b = 0
Debug.Print c(b) ' This will print 0, and b will equal 1.'
End Sub
Function c(d)
c = d
d = d + 1
End Function
立即窗口评估任何有效的VBA可执行语句。就像在代码编辑器中一样,只需在立即窗口中输入一条语句。它可以快速执行VBA代码,并且可以保存许多其他字符,因为:
这是“即时窗口”中以标签代码高尔夫回答PPCG帖子的VBA代码示例:不带A的字母A
?Chr(88-23);
乔凡回答。
图片来源: Excel Campus
a="value":?a
首先设置的值a
,然后打印它。
与循环结合使用时,某些条件检查是多余的。例如,For
如果起始条件超出运行条件的范围,则不会处理循环。
换句话说,这(49个字符):
If B > 0 Then
For C = A To A + B
'...
Next
End If
可以变成这个(24个字符):
For C = A To A + B ' if B is 0 or less, then the code continues past Next, unabated.
'...
Next
在大多数情况下,在VBA中,您Option Explicit
可以省去(无论如何,默认情况下通常都会省略)并跳过Dim
许多变量。
这样做,(96个字符):
Option Explicit
Sub Test()
Dim S As String
Dim S2 As String
S = "Test"
S2 = S
MsgBox S2
End Sub
变成这个(46个字符):
Sub Test()
S = "Test"
S2 = S
MsgBox S2
End Sub
如果需要使用某些对象(例如,数组),则可能仍需要Dim
该变量。
Evaluate()
和 []
如前所述,使用方括号[A1]
符号可以减少硬编码的范围调用。但是,它不仅具有更多用途。
根据MSDN文档,该Application.Evaluate()
方法采用单个参数,即Name
Microsoft Excel的命名约定定义的a 。
NB [string]
是简写形式Evaluate("string")
(请注意""
表示字符串数据类型的语音标记),尽管最后有一些重要的区别。
那么,就使用而言,这意味着什么呢?
从本质上讲,它[some cell formula here]
代表一个Excel工作表中的单元格,您可以将几乎任何内容放入其中,并从中获得与普通单元格一样的任何内容
总结,带有例子
[B7]
返回对该单元格的引用?[B7].Address
返回"B$7$"
[A1:B5]
返回对A1:B5
(Range)的范围引用[A1:B5 A3:D7]
返回对A3:B5
(相交)的范围引用[A1:B5,C1:D5]
返回A1:D5
(技术上A1:B5,C1:D5
)(Union)的范围引用[myRange]
参考A1:G5[Table1]
(可能对codegolf没什么用)Evaluate()
或[]
[SUM(1,A1:B5,myRange)]
返回范围myRange范围内的值的算术总和,此处引用的是工作簿名称,而不是VBA变量[IF(A1=1,"true","false")]
(比vba短1个字节Iif([A1]=1,"true","false")
)[CONCAT(IF(LEN(A1:B7)>2,A1:B7&" ",""))]
-将长度大于2的范围内的所有字符串以空格连接!
运算符来引用一个单元格或另一个工作簿中定义的名称[[BOOK1]Sheet1!A1]
在BOOK1中返回对A1的范围引用,或者['[MY WORKBOOK.XLSM]Sheet1!'A1]
在MY WORKBOOK
'
名称中带有空格的for工作簿,以及默认命名工作簿(BOOK+n
)缺少扩展名注意:我在SO上询问了有关此信息的问题,因此请看那里以获得更好的解释
与输入内容类似,输出内容包括工作表单元格可以返回的所有内容。这些是标准Excel数据类型(及其等效的VBA):
Boolean
)String
)Double
)Variant/Error
)(这些是不间断的错误,即它们不停止代码执行,?[1/0]
可以正常执行)但是有些事情可以返回,而单元格则不能:
Range
)(请参阅以上部分)Variant()
)如图所示,[]
可用于评估返回标准Excel数据类型之一的数组公式;例如[CONCAT(IF(LEN(A1:B7)>2,A1:B7&" ",""))]
返回Text
。但是Evaluate
也可以返回Variant
类型的数组。这些可以是
硬编码:
[{1,2;3,4}]
-输出2D数组:,
是列分隔符,用于;
分隔行。可以输出一维数组
数组公式:
[ROW(A1:A5)]
-输出2D数组{1,2,3,4,5}
,即(2,1)是第二项(但某些函数输出1D数组)
[LEN(A1:A5)]
仅输出范围的第一个单元格中的文本长度
Split([CONCAT(" "&LEN(A1:A5))])
给出一维数组0到5,其中第一项为空
[INDEX(LEN(A1:A5),)]
是另一种解决方法,本质上,您必须使用数组处理函数来获得所需的数组返回行为,类似于添加无意义的操作RAND()
以使工作表公式易变。
Evaluate()
与 []
Evaluate()
和之间存在一些差异[]
,需要注意
Evaluate("SUM(B1,1,"&v &",2)")
将总结[B1]
,1
,2
和可变v
数组
返回数组时,只能将Evaluate与数组索引一起使用,因此
v=Evaluate("ROW(A1:A5)")(1,1) ''#29 bytes
相当于
i=[ROW(A1:A5)]:v=i(1,1) ''#23 bytes
i=[ROW(A1:A5)]:v=i(2,1):?v
Next
报表Next:Next:Next
可能会浓缩为
Next k,j,i
其中对于迭代器For
环路i
,j
以及k
-按照这个顺序。
例如以下(69字节)
For i=0To[A1]
For j=0To[B1]
For k=0To[C1]
Debug.?i;j;k
Next
Next
Next
可以压缩到65字节
For i=0To[A1]
For j=0To[B1]
For k=0To[C1]
Debug.?i;j;k
Next k,j,i
至于这如何影响格式和缩进,我认为处理此问题的最佳方法是将下一条语句与最外层的for语句对齐。例如。
For i=0To[A1]
For j=0To[B1]
For k=0To[C1]
Debug.?i;j;k
Next k,j,i
If
陈述使用条件If ... Then ... Else
检查分配变量时,可以End If
通过将整个检查放在一行上来消除,从而减少使用的代码量。
例如,这(37个字符):
If a < b Then
c = b
Else
c = a
End If
可以减少到30个字符
If a < b Then c = b Else c = a
如果您有多个嵌套条件,则也可以通过以下方式将它们最小化:
If a Then If b Then If c Then Z:If d Then Y:If e Then X Else W Else V:If f Then U 'Look ma! No "End If"!
注意,:
允许您在一个If
块中添加多个行/命令。
在这种简单情况下,通常也可以Else
通过在If
检查前将变量设置为25个字符来删除:
c = a
If a < b Then c = b
更好的是,可以使用IIf()
函数(20个字符)将以上内容简化为:
c = IIf(a < b, b, a)
Range("A1")
和点赞电话Range("A1").Value
(17字节)和较简单的Range("A1")
(11字节)可以减少到[A1]
(4字节)
[]
replace Evaluate()
不仅比范围调用更通用。例如,您可以将其替换WorksheetFunction.FuncName(args)
为just [FuncName(args)]
,例如?[SUMPRODUCT({1,3,5},{2,7,-1})]
或非常有用的[MIN(1,2,3)]
/[MAX(1,2,3)]
Evaluate("str")
或者[str]
在VBA中速记功能非常强大,我最近才发现它,而且我猜想它对打高尔夫球也很有用!
VBA会自动格式化以增加很多实际不需要的间距。在meta上有一个答案,这对我来说很有意义,为什么我们可以取消通过自动格式化添加的字节。不过,重要的是要始终确保您没有卸下太多东西。例如,这是我的答案仅通过删除空格就减少了近22%:
原始版本:(188字节)
Sub g(n)
For i = 0 To 1
For x = -3 To 3 Step 0.05
y = n ^ x * Cos(Atn(1) * 4 * x)
If y < m Then m = y
If i = 1 Then Cells(500 * (1 - y / m) + 1, (x + 3) * 100 + 1) = "#"
Next
Next
End Sub
精简版:(146字节)
Sub g(n)
For i=0To 1
For x=-3To 3Step 0.05
y=n^x*Cos(Atn(1)*4*x)
If y<m Then m=y
If i=1Then Cells(500*(1-y/m)+1,(x+3)*100+1)="#"
Next
Next
End Sub
如果将简化版本复制/粘贴到VBA中,它将自动扩展为原始版本。您可以在删除空格有效的地方玩耍。到目前为止,我发现的所有命令似乎都遵循以下模式:期望VBA出现某个命令,因为没有它,它不是有效的代码。到目前为止,我发现了一些:
+-=/*^
等To
和Step
在For
声明中:For x=-3To 3Step 0.05
To
,&
,Then
等),如果它由一个立即诸如数字前缀,)
,?
,%
,等。&
组合字符串之后:Cells(1,1)=Int(t)&Format(t,":hh:mm:ss")
If s=StrReverse(s)Then
Replace(Space(28)," ",0)
?
vs之类的东西Print
是可以接受的,但是像&
在一个变量之后立即Debug.?a&"z"
给出类型声明,例如gives Debug.Print a&; "z"
。;
添加的字符对于代码的运行至关重要-是否仍然允许这样做?
If i=1 Then
可能会If i=1Then
,因为作为一般规则如下文字保留字,是一个数字,)
,?
,%
,...等,并不需要由分离空间
)
(或任何其他非数字文字)和&
像素艺术是迄今为止Excel最强大的领域之一,因为不需要构造画布,因为它已经为您提供了-您需要做的只是做一些小调整
Cells.RowHeight=48
或者,也可以再增加1个字节,但使用起来要容易得多
Cells.ColumnWidth=2
任何Range
物体都可以通过调用来着色
`MyRangeObj`.Interior.Color=`ColorValue`
注意:这可以并且应该与该Wiki上提到的其他技巧结合使用,例如使用[]
符号(例如[A1:R5,D6]
)引用范围而不是使用a Cells(r,c)
或aRange(cellAddress)
调用。此外,如该Wiki所述,此值可以与负色值组合以降低颜色参考的大小
范围参考
细胞 A1
可以通过以下任何方式引用
Range("A1")
Cells(1,1)
[A1]
和范围 A1:D4
可以通过以下任何一种方式引用
Range("A1:D4")
Range("A1").Resize(4,4)
Cells(1,1).Resize(4,4)
[A1].Resize(4,4,)
[A1:D4]
颜色参考
Black 0
White -1
Red 255
Aqua -256
当经常使用某些功能时,请将它们重新分配给用户定义的功能。
以下代码(127个字符)可以减少为:
Sub q()
w = 0
x = 1
y = 2
z = 3
a = Format(w, "0.0%")
b = Format(x, "0.0%")
c = Format(y, "0.0%")
d = Format(z, "0.0%")
End Sub
至(124个字符):
Sub q()
w = 0
x = 1
y = 2
z = 3
a = f(w)
b = f(x)
c = f(y)
d = f(z)
End Sub
Function f(g)
f = Format(g, "0.0%")
End Function
结合使用ByRef技巧,您可以保存更多字符(最多114个):
Sub q()
w = 0
x = 1
y = 2
z = 3
a = f(w)
b = f(x)
c = f(y)
d = f(z)
End Sub
Sub f(g)
g = Format(g, "0.0%")
End Sub
明智地执行此操作,因为VBA会占用很多字符来定义Function
。所述第二码块实际上是比所述第一与较大的任何数量少的Format()
呼叫。
a = f(w)
可以简化为f w
通过输入变量输入Sub
例程和Function
s
Public Sub A(ByRef B as String)
可能减少到
Sub a(b$)
在Public
与ByRef
电话是VBA,因而隐含的默认值,并可能(几乎)总是被丢弃。
类型文字$
强制b
为类型String
。
其他类型文字
!
单@
货币#
双%
整数$
串&
长^
LongLong(仅64位)此外,通常可以将输入变量保留为默认类型,Variant
并且不处理任何基于类型的错误。例如。Sub E(F)
其中F
应该是类型Boolean[]
(将传递给例程,如E Array(True, False, False)
)
通过输入到Sub
例程和立即窗口函数Cells
VBA没有功能齐全的控制台,因此没有任何官方的 STDIN,因此允许一些通过传递输入。
在excel中,通常接受从一个单元格或一系列单元格中获取输入,这可以像
s=[A1]
会隐式地将其.value
从单元格中放入[A1]
(也可以称为cells(1,1)
或range("A1")
示例问题:在消息框中显示输入
通过子程序 Sub A:msgbox[A1]:End Sub
通过即时窗口功能 msgbox[A1]
通过条件编译参数输入
VBA项目支持从命令行或通过VBAProject属性获取参数(通过项目浏览器查看-> [您的VBA项目]-(右键单击)-> VBAProject属性->条件编译参数)
这对于错误代码挑战非常有用
给定条件编译参数n=
[some_value],这允许基于的值执行将生成错误代码的代码n
。请注意,这需要为n=
VBAProject属性窗格的条件编译参数部分中的代码增加2个字节。
范例程式码
...
#If n=3 then
return '' Produces error code '3', Return without GoSub
#ElseIf n=20 then
resume '' Produces error code '20', Resume without Error
#EndIf
...
通过功能值输出
在这里不必多说,下面引用的一般形式要尽可能紧凑。
Public Function A(b)
...
A=C
End Function
注意:绝大多数情况下,将方法转换为子例程并输出到VBE立即窗口的字节更多(请参见下文)
从Sub
例程输出Function
通过VBE Instants窗口 s
输出到VBE立即窗口(又称VBE调试窗口)是VBA应对基于文本的挑战的一种常见输出方法,但是,重要的是要记住,Debug.Print "Text"
通话可能会打高尔夫球。
Debug.Print "Text"
在功能上与
Debug.?"Text"
作为?
自动格式化为Print
。
从输出 Sub
通过其他方法例程和VBE Instants Window函数
在极少数情况下,当情况恰到好处时,您可以从VBA可用的一些更简单的输入中获取输入,例如字体大小调整器,字体选择器和缩放。(例如,模拟Word字体大小选择器)
因为StackExchange使用Markdown和Prettify.js,因此可以在编码答案中添加语言标记,这通常会使它们看起来更加专业。尽管我不能保证这会使您在VBA中打高尔夫球更好,但我可以保证它会使您看起来像自己。
添加以下任一标志将进行转换
Public Sub a(ByRef b As Integer) ' this is a comment
至
Public Sub a(ByRef b As Integer) ' this is a comment
VBA语言标签
<!-- language: lang-vb -->
<!-- language-all: lang-vb -->
注意:后者转换答案中的所有代码段,而前者仅转换紧随其后的代码段
lang-vb
嗯?-奇怪的是,这种格式比lang-vba
vba答案的格式更好。
lang-vba
将提供突出显示,但实际上它只是默认的突出显示。显然,VBA实际上尚未在Prettify.js中实现,因此我们必须坚持VB突出显示
If .. Then
检查正如在其他语言,多If
检查通常可以组合成单个线,从而允许使用的And
/ Or
(即&&
/ ||
C和其他),其在VBA取代了一个Then
和一个End If
。
例如,使用嵌套条件(93个字符):
'There are MUCH easier ways to do this check (i.e. a = d).
'This is just for the sake of example.
If a = b Then
If b = c Then
If c = d Then
MsgBox "a is equal to d"
End If
End If
End If
可以变成(69个字符):
If a = b And b = c And c = d Then
MsgBox "a is equal to d"
End If
这也适用于非嵌套条件条件。
考虑(84个字符):
If a = b Then
d = 0
End If
If c = b Then
d = 0
End If
可以变成(51个字符):
If a = b Or c = b Then
d = 0
End If
d=iif(a=b or c=b,0,d)
有时将字符串分割成单个字符可能很有用,但是在VBA中手动执行此操作可能需要一些代码。
ReDim a(1 To Len(s))
' ReDim because Dim can't accept non-Const values (Len(s))
For i = 1 To Len(s)
a(i) = Mid(s, i, 1)
Next
相反,您可以使用单行,相对较少的功能链来完成工作:
a = Split(StrConv(s, 64), Chr(0))
这会将您的字符串分配s
给Variant
array a
。但是要小心,因为数组中的最后一项将是一个空字符串(""
),需要适当处理。
其工作方式如下:该StrConv
函数将将a转换为String
您指定的另一种格式。在这种情况下,64 = vbUnicode
,因此它将转换为unicode格式。处理简单的ASCII字符串时,结果是""
在每个字符后插入一个空字符(不是空字符串)。
接下来,Split
将String
使用空字符将结果转换为数组Chr(0)
作为分隔符。
重要的是要注意,Chr(0)
它与空字符串不同""
,并且使用Split
on ""
不会返回您可能期望的数组。这同样适用vbNullString
(但如果您打高尔夫球,那为什么首先要使用这样的冗长常量?)。
With
(有时!请参见脚注)With
如果重复使用某些对象,则使用该语句可以大大减少代码大小。
即这(80个字符):
x = foo.bar.object.a.value
y = foo.bar.object.b.value
z = foo.bar.object.c.value
可以编码为(79个字符):
With foo.bar.object
x = .a.value
y = .b.value
z = .c.value
End With
以上甚至不是最好的情况。如果对进行任何使用Application
,例如Excel.Application
从Access中使用,则改进将更为显着。
*视情况而定,With
可能比这更有效(64个字符):
Set i = foo.bar.object
x = i.a.value
y = i.b.value
z = i.c.value
考虑更换
Do While a<b
'...
Loop
要么
Do Until a=b
'...
Loop
具有过时但较低的字节数
While a<b
'...
Wend
如果您需要退出Sub
或Function
过早退出,则可以使用Exit ...
For i=1To 1000
If i=50 Then Exit Sub
Next
考虑 End
For i=1To 1E3
If i=50 Then End
Next
请注意,这会End
暂停所有代码执行并清除所有全局变量,因此请明智使用
For
和End
)以反映该案件100
将永远不会得到解决,并添加了一个不必要的字节
Debug.Print
和Print
通话Debug.Print [some value]
(12字节;请注意尾随空格)可以减少为
Debug.?[some value]
(7字节;请注意缺少尾随空间)。
同样,
Print
(6字节)可减少为
?
(1字节)。
此外,当在匿名VBE立即窗口函数的上下文中操作时,该Debug
语句可以完全删除,而?
可以假定通过打印到VBE立即窗口通过是STDIN / STDOUT。
打印字符串时,也可以使用特殊字符代替&
。这些允许在打印的内容或空格删除中使用其他格式
连接变量字符串,而不是
Debug.Print s1 &s2
您可以使用分号 ;
Debug.?s1;s2
只要没有歧义,此分号是连续字符串的默认行为,因此它们是有效的:
Debug.?s1"a"
Debug.?"a"s1
但不是
Debug.?s1s2 'as this could be interpreted as a variable named "s1s2", not 2 variables
'use Debug.?s1 s2 instead (or s1;s2)
Debug.?"a""b" 'this prints a"b, so insert a space or ; for ab
注意a; 在行的末尾禁止换行,因为默认情况下,每次打印后都会添加换行。VBA代码返回的字节计数尚有争议
要与制表符连接,请使用逗号,
(实际上是14个空格,但根据)
Debug.?s1,s2 'returns "s1 s2"
最后,您可以使用类型声明而不是;来连接字符串,每个声明对格式都有轻微的影响。对于以下所有a = 3.14159
内容,第一行
Debug.?a&"is pi" -> " 3 is pi" 'dims a as long, adds leading and trailing space to a
Debug.?a!"is pi" -> " 3.14159 is pi" 'dims a as single, adds leading and trailing space
Debug.?a$"is pi" -> "3.14159is pi" 'dims a as string, no spaces added
Array()
Choose()
Select
或If...Then
当基于另一个变量的值分配变量时,有意义的是使用If...Then
检查写出步骤,如下所示:
If a = 1 Then
b = "a"
ElseIf a = 2 Then
b = "c"
'...
End If
但是,如果要检查的变量不止一个或两个,那么这可能会占用大量代码空间(无论如何,通常还有更好的方法来执行此操作)。
相反,该Select Case
语句通过将所有内容封装在一个块中来帮助减少检查的大小,如下所示:
Select Case a
Case 1:
b = "a"
Case 2:
b = "c"
'...
End Select
这样可以减少代码的数量,但是对于像这样的非常简单的情况,有一个甚至更有效的方法:Choose()
该函数将基于传递给它的值从列表中选择一个值。
b = Choose(a,"a","c",...)
选择的选项(a
在这种情况下)是作为第一个参数传递的整数值。所有后续参数都是可以选择的值(像大多数VBA一样,为1索引)。值可以是任何数据类型,只要它与所设置的变量匹配即可(即对象没有Set
关键字就无法工作),甚至可以是表达式或函数。
b = Choose(a, 5 + 4, String(7,"?"))
另一个选择是使用该Array
函数在保存另一个字符的同时获得相同的效果:
b = Array(5 + 4, String(7,"?"))(a)
IIf()
或另一个结合使用Choose()
:A1=IIf(a=Choose(b,c,d,e),Choose(Choose(f,g,h,i),j,k,l),Choose(IIf(m=n,Choose(p,q,r,s),IIf(t=u,v,w)),x,y,z))
由于Excel处理颜色的方式(无符号的6个字符的十六进制整数),您可以使用带负号的整数,其中excel将仅使用正确的6个字节来分配颜色值
这有点令人困惑,因此下面提供了一些示例
假设您要使用白色,该颜色存储为
rgbWhite
相当于
&HFFFFFF ''#value: 16777215
若要向下推算,我们需要做的是找到一个以终止的负十六进制值,FFFFFF
并且由于in的负十六进制值必须采用从()到()倒数的FFFFXXXXXX
(这样X
的有效十六进制)格式。FFFFFFFFFF
-1
FFFF000001
-16777215
))。
知道了这一点,我们可以将公式概括为
Let Negative_Color_Value = -rgbWhite + Positive_Color_Value - 1
= -16777215 + Positive_Color_Value - 1
= -16777216 + Positive_Color_Value
使用此功能,可以进行一些有用的转换
rgbWhite = &HFFFFFF = -1
rgbAqua = &HFFFF00 = -256
16747627 = &HFF8C6B = -29589
rgbWhite
= 2^24-1
尽管如果您错过-1可能会进一步减少到大约-1,则可能会进一步减少
&000080: 2^7, &000100: 2^8, &000200: 2^9, &000400: 2^10, &000800: 2^11, &001000: 2^12, &002000: 2^13, &004000: 2^14, &008000: 2^15, &010000: 2^16, &01FFFF: 2^17-1, &020000: 2^17, &03FFFF: 2^18-1, &040000: 2^18, &07FFFF: 2^19-1, &080000: 2^19, &0FFFFF: 2^20-1, &100000: 2^20, &1FFFFF: 2^21-1, &3FFFFF: 2^22-1, &400000: 2^22, &7FFFFF: 2^23-1
nb不一定完整,但我认为我做得相当透彻
LongLong
64位VBA中的幂和s求幂的一般形式
A to the power of B
可以在VBA中表示为
A^B
但是,只有在Office的32位安装中,在 Office的64位安装中,您可以无错误地表示的最短方法是
A ^B
这是因为在64位版本的VBA中^
,它既用作指数文字,又用作LongLong
类型声明字符。这意味着可能会出现一些看起来很奇怪但有效的语法,例如
a^=2^^63^-1^
分配变量a
以保存a的最大值Longlong
对于需要解决方案来保存恒定数据的挑战,将数据压缩为单个字符串然后在字符串中进行迭代以获取数据可能是有用的。
在VBA中,任何字节值都可以直接转换为
Chr(byteVal)
并且a long
或integer
value可以转换为两个字符
Chr(longVal / 256) & Chr(longVal Mod 256)
因此,对于byte
数组,压缩算法看起来像
For Each Var In bytes
Select Case Var
Case Is = Asc(vbNullChar)
outstr$ = outstr$ & """+chr(0)+"""
Case Is = Asc(vbTab)
outstr$ = outstr$ & """+vbTab+"""
Case Is = Asc("""")
outstr$ = outstr$ & """"""
Case Is = Asc(vbLf)
outstr$ = outstr$ & """+vbLf+"""
Case Is = Asc(vbCr)
outstr$ = outstr$ & """+vbCr+"""
Case Else
outstr$ = outstr$ & Chr$(Var)
End Select
Next
Debug.Print "t="""; outstr$
注意该Select Case
部分是由于字符而实现的,这些字符可能不会作为文字存储在字符串中。
从结果字符串中,看起来像
t="5¼-™):ó™ˆ"+vbTab+"»‘v¶<®Xn³"+Chr(0)+"~ίšÐ‘š;$ÔÝ•óŽ¡¡EˆõW'«¡*{ú{Óx.OÒ/R)°@¯ˆ”'®ïQ*<¹çu¶àªp~ÅP>‹:<«a°;!¾y›/,”Ì#¥œ5*B)·7
然后可以使用Asc
和Mid
函数提取数据,例如
i=Asc(Mid(t,n+1))
在某些情况下,VBA允许在需要常量值的表达式中使用未列出或不适当的常量。这些通常是遗留值,并且长度短于适当值。
例如,当让rng.HorizantalAlignment
属性保留值时,可以使用以下值 。
This means, for example that setting a cell to having its text centered with
rng.HorizantalAlignment=-4108
may be shortened down to
rng.HorizantalAlignment=3
by replacing the improper constant value 3
for the proper value -4108
. Note that if you fetch the rng.HorizantalAlignment
property value, it will return the proper value. In this case, that would be -4108
.
When a constant single dimensional set of numerics of mixed length, is needed, it shall be more efficient to use [{...}]
notation to declare a range and then coerce that into a numeric array rather than to use the Split(String)
notation or similar.
Using this method, a change of shall be accrued for all .
For instance,
x=Split("1 2 34 567 8910")
may be written as
x=[{1,2,34,567,8910}]
It is further worth noting that while this method does not allow for direct indexing, it does allow for iteration over the for loop directly, ie
For Each s In[{1,3,5,7,9,2,4,6,8}]