Tag: vba

  • recordset.clone is not working

    我修改了一段以前写的 vba,用到了 recordset.clone,没想到由于 vba 本身的 bug,克隆并没有进行,recordset.clone 返回值仍然是原记录集的引用。我在返回值记录集进行了 recordset.delete,结果把我原本想保持不动的原记录集里的记录给删了。

    那个恨啊!实在没想到 recordset.clone 只引用不克隆,害我为恢复原记录折腾了很久。我没兴趣深究原因,就当是 vba bug,就算是我调用参数配置不当,recordset.clone 克隆不成功也不能随随便便返回一个值而不抛出错误。

    既然 recordset.clone 不能用,找了一个前辈 Robert Gelb 写的函数来做真正的克隆。

    Public Function Clone(ByVal oRs As ADODB.Recordset, _
        Optional ByVal LockType As ADODB.LockTypeEnum = adLockUnspecified) As ADODB.Recordset
    
        Dim oStream As ADODB.Stream
        Dim oRsClone As ADODB.Recordset
    
        'save the recordset to the stream object
        Set oStream = New ADODB.Stream
        oRs.Save oStream
    
        'and now open the stream object into a new recordset
        Set oRsClone = New ADODB.Recordset
        oRsClone.Open oStream, , , LockType
    
        'return the cloned recordset
        Set Clone = oRsClone
    
        'release the reference
        Set oRsClone = Nothing
    End Function
    
  • Workaround to row cannot be located for updating

    用ADO + ODBC操作Mysql database,用起来总不顺手。经常有莫名其妙的错误,其中不乏connector bugs。这些bugs不是我等能解决的,只有尽量不去触发bugs才是上策。

    比如,我今天在使用recordset.update时被提示”Row cannot be located for updating. Some values may have been changed since it was last read.” 我排错了好久,最后总结出以下best practices:

    • 避免使用”SELECT *”来查询,用到哪些字段就SELECT那些字段;
    • 如果SELECT中的字段中,某些值没有改变,recordset.update 可能会出错(也就是说,所有字段值都被改变后才能update)
    • Connector/ODBC Application Specific Tips特别提到Access can’t always handle the MySQL DATE column properly. If you have a problem with these, change the columns to DATETIME.
    • Float或double类型字段值,避免用Float或Double运算后的值直接去更新,应该保留必要精度后的值去更新。例如,x和y都是double类型,total字段也是double类型,不要用x+y去更新total字段,若total只要保留两位小数,就用formatnumber(x+y, 2)去更新total。

    综上,为了简单起见,如果要update a record,干脆先删除这条record,再recordset.addnew,赋予新值。对于新鲜记录的更新,以上四种可能的错误均没有出现。

  • VBA字符串精确比较

    我实在没想到在VBA里,(“abc” = “ABC”) = true。

    为了debug这个被我认为 false的判断,我找了好久。找到了已经想通了,从DOS到Windows,微软不是一直在营造一种大小写不敏感的气氛吗?只是我没估计到从程序员这么严谨的角度,竟然也是忽略字符串大小写。可能我越来越Linux了,对Windows这一套哲学越来越不适应了。

    不过,VBA里要精确比较字符串也是做得到的: StrComp(String1, String2, vbBinaryCompare).

  • 我离微软而去

    曾几何时,我是那么地崇拜Microsoft,崇拜Bill Gates,崇拜Windows, Office, Exchange,崇拜Desktop 1000/2000/4000/8000…

    现在,Windows仍然每天用,MS Office也是我用得最熟练的Office软件,vba我虽不精通,但编几个小function满足一下所谓的办公自动化的要求还是可以的。但是,考虑到将来,我今天正式作出一个痛苦的决定,不再投资时间在vba上,不再钻研Microsoft其他高深的产品,比如Microsoft Dynamics, SBS, SitePoint, etc.
    省下来的时间我要全面拥抱微软产品的替代方案。对于像我这样已经被微软洗过脑的人,可能要花较长的时间来熟悉其它产品的设计思维,那就从现在开始吧。我想从最近的一个项目入手,用OpenOffice Basic替代以前的VBA,但今天玩了一整天的OpenOffice Basic, 连个对话框也没搞出来,万事开头难啊。

    可能有些人早认为微软不是以后的主流,但我还没有100%确信这一点,现在退出我心里也忐忑,有点像赌博。我希望我的选择顺应了一种趋势, 我希望微软少了我就不行了,呵呵。