VBA不会短路
VBA不支持短路 - 显然是因为它只有按位和/或/不等操作.从VBA语言规范:"逻辑运算符是对其操作数执行按位计算的简单数据运算符." 从这个角度来看,使用true = &H1111和设计VBA是有道理的false = &H0000:这样,逻辑语句可以被评估为按位运算.
缺少短路可能会导致问题
性能:在ReallyExpensiveFunction()评估此语句时将始终运行,即使条件左侧的结果不需要
If IsNecessary() And ReallyExpensiveFunction() Then
'...
End If
错误:如果MyObj为Nothing,则此条件语句将导致运行时错误,因为VBA仍将尝试检查值 Property
If Not MyObj Is Nothing And MyObj.Property = 5 Then
'...
End If
我用来实现短效行为的解决方案是嵌套If的
If cond1 And cond2 Then
'...
End If
Run Code Online (Sandbox Code Playgroud)
变
If cond1 Then
If cond2 Then
'...
End If
End If
Run Code Online (Sandbox Code Playgroud)
通过这种方式,If语句给出了类似短路的行为,即不打算评估cond2是否cond1存在False.
如果存在Else子句,则会创建重复的代码块
If Not MyObj Is Nothing And MyObj.Property …Run Code Online (Sandbox Code Playgroud) 我做错了什么,或者VBA Mod操作符实际上不适用于像双打这样的浮点值?
所以我总是假设VBA Mod操作符可以使用基于VB文档的 Doubles ,但是在试图弄清楚为什么我的舍入函数不起作用时,我发现了一些意想不到的Mod行为.
这是我的代码:
Public Function RoundUp(num As Double, Optional nearest As Double = 1)
RoundUp = ((num \ nearest) - ((num Mod nearest) > 0)) * nearest
End Function
Run Code Online (Sandbox Code Playgroud)
RoundUp(12.34)返回12而不是13如此我挖得更深一些,发现:
12.5 Mod 1返回0类型为Long的返回类型,而我的预期值为0.5,类型为Double.
结论
正如@ ckuhn203在答案中指出的那样,根据VBA规范,
模数或余数运算符将number1除以number2(将浮点数舍入为整数),并仅返回余数作为结果.
和
通常,结果的数据类型是包含Long的Byte,Byte变量,Integer,Integer变量,Long或Variant,而不管结果是否为整数.任何小数部分都被截断.
为了我的目的,我需要一个浮点模数,所以我决定使用以下内容:
Public Function FMod(a As Double, b As Double) As Double
FMod = a - Fix(a / b) * b
'http://en.wikipedia.org/wiki/Machine_epsilon
'Unfortunately, this function can only …Run Code Online (Sandbox Code Playgroud) 我想为我的类添加一个功能,所以我可以在for-each循环中使用它们.
我写了一些我要迭代的哈希映射,arraylists,队列,集等等.现在我正在寻找一种方法来实现IUnknown类来构建自定义迭代器.
我已经知道如何使用了
private objPeople as Collection
Public Property Get NewEnum() As IUnknown
Attribute NewEnum.VB_UserMemId = -4
Attribute NewEnum.VB_MemberFlags = "40"
Set NewEnum = objPeople.[_NewEnum]
End Property
Run Code Online (Sandbox Code Playgroud)
但那里的所有例子都基于Collection类,我不想使用它.
我想要关注的是尝试实现IUnknown接口,但我没有找到任何关于如何做到这一点的参考.
我在Java,C++,C#等方面有丰富的经验,所以我认为即使在VBA中也可以实现这一点,甚至可以使用API调用这样的东西.
我该如何实现这个功能?
Public Function ArraySlice(arr As Variant, dimension as Long, index as Long) As Variant
'Implementation here
End Function
Run Code Online (Sandbox Code Playgroud)
假设我想要一个数组切片.我在该维度上指定了一个数组,一个维度和一个索引,我想要切片.
举一个具体的例子,假设我有以下5x4 2D数组
0 1 2 3 4
______________
0| 1 1 2 3 1
1| 3 4 2 1 5
2| 4 5 3 2 6
3| 3 5 2 1 3
Run Code Online (Sandbox Code Playgroud)
如果水平尺寸为1且垂直尺寸为2,则返回值ArraySlice(array, 1, 3)将为1x4 2D阵列.选定的维度2被展平,唯一剩下的值是最初在维度2的索引3处的值:
0
____
0| 3
1| 1
2| 2
3| 1
Run Code Online (Sandbox Code Playgroud)
你会如何在VBA中实现这一点?我能想到的唯一实现将涉及CopyMemory,除非我限制了允许的维度数量并对每种情况进行硬编码.
注意:这是我如何获得数组的尺寸
UPDATE
以下是一些操作示例
对于2D阵列
0 1 2 3 4
______________
0| …Run Code Online (Sandbox Code Playgroud) 我已经安装上genymotion模拟器的Facebook应用程序nexus 4.1.1
版本2.0.1的Genymotion.
但它不起作用......
安装成功后,我在家中看到了Facebook应用程序的快捷方式,但是当我按下一个黑屏时出现大约三秒钟并关闭
你知道如何解决这个问题吗?
我正在为传出消息设计动态缓冲区.数据结构采用具有字节数组缓冲区作为成员的节点队列的形式.不幸的是,在VBA中,Arrays不能成为类的公共成员.
例如,这是禁止编译,不会编译:
'clsTest
Public Buffer() As Byte
Run Code Online (Sandbox Code Playgroud)
您将收到以下错误:"常量,固定长度字符串,数组,用户定义类型和Declare语句不允许作为对象模块的公共成员"
好吧,没关系,我只是把它变成一个私有成员,拥有公共财产访问者......
'clsTest
Private m_Buffer() As Byte
Public Property Let Buffer(buf() As Byte)
m_Buffer = buf
End Property
Public Property Get Buffer() As Byte()
Buffer = m_Buffer
End Property
Run Code Online (Sandbox Code Playgroud)
...然后在模块中进行一些测试以确保其有效:
'mdlMain
Public Sub Main()
Dim buf() As Byte
ReDim buf(0 To 4)
buf(0) = 1
buf(1) = 2
buf(2) = 3
buf(3) = 4
Dim oBuffer As clsTest
Set oBuffer = New clsTest
'Test #1, the assignment
oBuffer.Buffer = buf 'Success!
'Test #2, …Run Code Online (Sandbox Code Playgroud) 似乎许多语言,包括C/C++和Java,都有逻辑Not(转换0到1,反之亦然)和Bitwise Not(按位反转AKA的补码).在Visual Basic中,Not只是按位,并且True值为-1.VB是以这种方式实现的吗?
如果它是从BASIC继承的一些遗迹,那么它是否代表了1964年(BASIC)与C(1972)等后期语言时代的思维变化?
假设我正在访问图数据结构中的节点.当我访问每个节点时,我会将其添加到"已访问"列表中.需要进行O(1)查找以验证我不会多次访问同一节点.
当然,如果每个节点都有一个关联的值,我可以使用常规的JavaScript对象(哈希表)来存储我的"访问"列表,但是假设我想知道节点是否可以评估为字符串.是否有支持O(1)对象查找的JavaScript数据结构?我怎么能实现一个?
(免责声明:我正在学习JavaScript)我有一个像这样的对象构造函数:
var Palette = function() {
this.colors = ["red", "green", "blue"];
this.getColorCombinations = function() {
var combos = [];
this.colors.forEach(function(a) {
this.colors.forEach(function(b) {
if(a !== b) {
combos.push([a, b]);
}
});
});
return combos;
};
}
var p = new Palette();
alert(JSON.stringify(p.getColorCombinations()));
Run Code Online (Sandbox Code Playgroud)
随着预期的输出:
[["red","green"],["red","blue"],["green","red"],["green","blue"],["blue","red"],["blue","green"]]
经过一些研究后,我意识到这不起作用,因为在内部匿名函数中,"this"指向全局对象而不是Palette实例.
我的问题是,处理这个问题的"JavaScript方式"是什么?我看到使用Apply,Bind,Call或简单地分配this给变量解决了类似的问题,但到目前为止,我还没有找到任何一种this在内部匿名函数中引用最佳实践的示例.
这是JsFiddle.(我将其修改为输出到div以便于文本复制)