分类目录归档:VBscript

VB实现类继承的另类方法

之前为了实现公司业务对比的功能,用VB写了个小工具去供应商处采集数据,通过本工具对业务进行对比。刚开始供应商比较少,没有按类的对象(类)的编写。随着供应商的增加,两三年下来,供应商已经增加到近20家,每家都有三四大类产品线。为了共用某些代码(XMLHTTP,正则,登录判断),代码都写到了一个模块里。

近期,有供应商改版了,需要对程序进行调整,发现仅采集模块就有1500行代码,基本都在一个过程(Sub)里,每改一次简直要疯一次。如果把公用方法写到一个类里,然后各个供应商都继承(Extend)这个类,岂不美哉。发现VB不是完全面向对象的语言,基本都是说道不可能。在贴吧一个帖子里(http://tieba.baidu.com/p/1795854449)提到VB6.0实现类的继承,用他的代码测试,也没有解决。简直是坑啊。。。。。实际他做到的是Implements。 继续阅读

巧用ASPJPEG做验证码识别程序

在写程序实现 发帖/回帖 中,验证码识别是一个非常重要的工具。今天我就来些这样一个工具。

首先需要创建文字表(A),然后去识别原图(B)。然后截出某字符的图片,比较第一个像素(0,0)的差值,第二个像素的差值(0,1)的差值,然后。。。。最终差值最小的就是识别出的字符。

说起来有点绕口,实际很简单。直接上代码了(VBS对图像处理较弱,所以用到ASPJPEG组件)。

下载地址:http://www.miaoqiyuan.cn/products/ocr.rar

继续阅读

ASP的Base64函数

  Const BASE_64_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  Private sBASE_64_CHARACTERS

  Function Base64encode(ByVal asContents)
    asContents = strUnicode2Ansi(asContents)
    Dim lnPosition,lsResult,Char1,Char2,Char3,Char4,Byte1,Byte2,Byte3,SaveBits1,SaveBits2,lsGroupBinary,lsGroup64,M4, len1, len2
    len1 = LenB(asContents)
    If len1 < 1 Then
      Base64encode = ""
      Exit Function
    End If
    M4 = len1 Mod 3
    If M4 > 0 Then asContents = asContents & String(3 - M4, Chr(0))
    '补足位数是为了便于计算
    If M4 > 0 Then
      len1 = len1 + (3 - M4)
      len2 = len1 - 3
    Else
      len2 = len1
    End If
    lsResult = ""
    sBASE_64_CHARACTERS = strUnicode2Ansi(BASE_64_CHARACTERS)
    For lnPosition = 1 To len2 Step 3
      lsGroup64 = ""
      lsGroupBinary = MidB(asContents, lnPosition, 3)
      Byte1 = AscB(MidB(lsGroupBinary, 1, 1)): SaveBits1 = Byte1 And 3
      Byte2 = AscB(MidB(lsGroupBinary, 2, 1)): SaveBits2 = Byte2 And 15
      Byte3 = AscB(MidB(lsGroupBinary, 3, 1))
      Char1 = MidB(sBASE_64_CHARACTERS, ((Byte1 And 252) \ 4) + 1, 1)
      Char2 = MidB(sBASE_64_CHARACTERS, (((Byte2 And 240) \ 16) Or (SaveBits1 * 16) And &HFF) + 1, 1)
      Char3 = MidB(sBASE_64_CHARACTERS, (((Byte3 And 192) \ 64) Or (SaveBits2 * 4) And &HFF) + 1, 1)
      Char4 = MidB(sBASE_64_CHARACTERS, (Byte3 And 63) + 1, 1)
      lsGroup64 = Char1 & Char2 & Char3 & Char4
      lsResult = lsResult & lsGroup64
    Next
    '处理最后剩余的几个字符
    If M4 > 0 Then
      lsGroup64 = ""
      lsGroupBinary = MidB(asContents, len2 + 1, 3)
      Byte1 = AscB(MidB(lsGroupBinary, 1, 1)): SaveBits1 = Byte1 And 3
      Byte2 = AscB(MidB(lsGroupBinary, 2, 1)): SaveBits2 = Byte2 And 15
      Byte3 = AscB(MidB(lsGroupBinary, 3, 1))
      Char1 = MidB(sBASE_64_CHARACTERS, ((Byte1 And 252) \ 4) + 1, 1)
      Char2 = MidB(sBASE_64_CHARACTERS, (((Byte2 And 240) \ 16) Or (SaveBits1 * 16) And &HFF) + 1, 1)
      Char3 = MidB(sBASE_64_CHARACTERS, (((Byte3 And 192) \ 64) Or (SaveBits2 * 4) And &HFF) + 1, 1)
      If M4 = 1 Then
        lsGroup64 = Char1 & Char2 & ChrB(61) & ChrB(61) '用=号补足位数
      Else
        lsGroup64 = Char1 & Char2 & Char3 & ChrB(61) '用=号补足位数
      End If
      lsResult = lsResult & lsGroup64
    End If
    Base64encode = strAnsi2Unicode(lsResult)
  End Function

  Function Base64decode(ByVal asContents)
    asContents = strUnicode2Ansi(asContents)
    Dim lsResult,lnPosition,lsGroup64, lsGroupBinary,Char1, Char2, Char3, Char4,Byte1, Byte2, Byte3,M4, len1, len2
    len1 = LenB(asContents)
    M4 = len1 Mod 4

    If len1 < 1 Or M4 > 0 Then
      '字符串长度应当是4的倍数
      Base64decode = ""
      Exit Function
    End If
    '判断最后一位是不是 = 号
    '判断倒数第二位是不是 = 号
    '这里m4表示最后剩余的需要单独处理的字符个数
    If MidB(asContents, len1, 1) = ChrB(61) Then M4 = 3
    If MidB(asContents, len1 - 1, 1) = ChrB(61) Then M4 = 2
    If M4 = 0 Then
      len2 = len1
    Else
      len2 = len1 - 4
    End If
    sBASE_64_CHARACTERS = strUnicode2Ansi(BASE_64_CHARACTERS)
    For lnPosition = 1 To len2 Step 4
      lsGroupBinary = ""
      lsGroup64 = MidB(asContents, lnPosition, 4)
      Char1 = InStrB(sBASE_64_CHARACTERS, MidB(lsGroup64, 1, 1)) - 1
      Char2 = InStrB(sBASE_64_CHARACTERS, MidB(lsGroup64, 2, 1)) - 1
      Char3 = InStrB(sBASE_64_CHARACTERS, MidB(lsGroup64, 3, 1)) - 1
      Char4 = InStrB(sBASE_64_CHARACTERS, MidB(lsGroup64, 4, 1)) - 1
      Byte1 = ChrB(((Char2 And 48) \ 16) Or (Char1 * 4) And &HFF)
      Byte2 = lsGroupBinary & ChrB(((Char3 And 60) \ 4) Or (Char2 * 16) And &HFF)
      Byte3 = ChrB((((Char3 And 3) * 64) And &HFF) Or (Char4 And 63))
      lsGroupBinary = Byte1 & Byte2 & Byte3
      lsResult = lsResult & lsGroupBinary
    Next
    '处理最后剩余的几个字符
    If M4 > 0 Then
      lsGroupBinary = ""
      lsGroup64 = MidB(asContents, len2 + 1, M4) & ChrB(65) 'chr(65)=A,转换成值为0
      If M4 = 2 Then '补足4位,是为了便于计算
        lsGroup64 = lsGroup64 & ChrB(65)
      End If
      Char1 = InStrB(sBASE_64_CHARACTERS, MidB(lsGroup64, 1, 1)) - 1
      Char2 = InStrB(sBASE_64_CHARACTERS, MidB(lsGroup64, 2, 1)) - 1
      Char3 = InStrB(sBASE_64_CHARACTERS, MidB(lsGroup64, 3, 1)) - 1
      Char4 = InStrB(sBASE_64_CHARACTERS, MidB(lsGroup64, 4, 1)) - 1
      Byte1 = ChrB(((Char2 And 48) \ 16) Or (Char1 * 4) And &HFF)
      Byte2 = lsGroupBinary & ChrB(((Char3 And 60) \ 4) Or (Char2 * 16) And &HFF)
      Byte3 = ChrB((((Char3 And 3) * 64) And &HFF) Or (Char4 And 63))
      If M4 = 2 Then
        lsGroupBinary = Byte1
      ElseIf M4 = 3 Then
        lsGroupBinary = Byte1 & Byte2
      End If
      lsResult = lsResult & lsGroupBinary
    End If
    Base64decode = strAnsi2Unicode(lsResult)
  End Function

  Function strUnicodeLen(ByVal asContents)
    '计算unicode字符串的Ansi编码的长度
    Dim asContents1
    Dim len1,k,i,asc1
    asContents1 = "a" & asContents
    len1 = Len(asContents1)
    k = 0
    For i = 1 To len1
      asc1 = Asc(Mid(asContents1, i, 1))
      If asc1 < 0 Then asc1 = 65536 + asc1
      If asc1 > 255 Then
        k = k + 2
      Else
        k = k + 1
      End If
    Next
    strUnicodeLen = k - 1
  End Function

  Function strUnicode2Ansi(ByVal asContents)
    '将Unicode编码的字符串,转换成Ansi编码的字符串
    Dim len1,i,VarChar,varAsc,varHex, varlow, varhigh
    strUnicode2Ansi = ""
    len1 = Len(asContents)
    For i = 1 To len1
      VarChar = Mid(asContents, i, 1)
      varAsc = Asc(VarChar)
      If varAsc < 0 Then varAsc = varAsc + 65536
      If varAsc > 255 Then
        varHex = Hex(varAsc)
        varlow = Left(varHex, 2)
        varhigh = Right(varHex, 2)
        strUnicode2Ansi = strUnicode2Ansi & ChrB("&H" & varlow) & ChrB("&H" & varhigh)
      Else
        strUnicode2Ansi = strUnicode2Ansi & ChrB(varAsc)
      End If
    Next
  End Function

  Function strAnsi2Unicode(asContents)
    '将Ansi编码的字符串,转换成Unicode编码的字符串
    Dim len1,i,VarChar,varAsc
    strAnsi2Unicode = ""
    len1 = LenB(asContents)
    If len1 = 0 Then Exit Function
    For i = 1 To len1
      VarChar = MidB(asContents, i, 1)
      varAsc = AscB(VarChar)
      If varAsc > 127 Then
        strAnsi2Unicode = strAnsi2Unicode & Chr(AscW(MidB(asContents, i + 1, 1) & VarChar))
        i = i + 1
      Else
        strAnsi2Unicode = strAnsi2Unicode & Chr(varAsc)
      End If
    Next
  End Function

用FileDB快速开发生成静态系统

最近要用到一套ASP生成静态的小系统,虽然说程序简单,但是写起来还是比较繁琐的,正好前几天写过一个:ASP文件存储方案(http://www.miaoqiyuan.cn/p/asp-filedb),用改类,可以直接快速开发生成ASP的系统。

  '加载模板
  '对于模板,不了解的,可以参考我以前写过的文章,当然也可以用任何asp的模板系统
  set p = new MYW3_TPL
  p.LoadTpl "tpl/chengyu.html"
  p.assign "Title","猫七"
  p.assign "WebHome",WebHome
  p.assign "WebSkin",WebSkin
  
  '/index.html
  url = "index"
  '/home/index.html
  'url = "home::index"
  '/home/1/2/333.html
  'url = "home::1::2::333"
  '生成静态
  ‘使用FileDB类,超级简单
  set f = new FileDB
  f.DBPath = "/"
  f.idxKey = url
  f.save(p.outHtml)

需要对FileDB的类做一下小的修改

Private Function getPath()
    Dim tmp
    getPath = replace(idxKey,"::","/") & ".html"
  End Function

ASP文本存储方案-FileDB

四月份做个一个短信系统,当时为了节省成本(使用万网的空间,不带SQL数据库空间便宜),使用了ASP+Access开发,最近需要升级,增加一个短信接口。发现现在Access的数据库竟然有170MB。我的天啊,因为查询比较少,不是很耗资源,所以没有检查出来。
仅仅六个月,数据库竟然到了170MB。随着客户业务的增长,可能再过六个月就要到500MB了,真恐怖。主要占空间大小的,就是存储的短信的发送号码,思考再三,决定将所有的保存到文本文件中。于是写下了一个暂时成为FileDB的asp类。

Class FileDB
  Dim fso,IdxKey,DBPath
  Private Sub Class_Initialize
    Set fso = Server.CreateObject("Scripting.FileSystemObject")
    idxKey = "demo::test"
    DBPath = "DataCenter/File_DB/"
  End Sub

  Private Function getPath()
    Dim tmp
    getPath = replace(idxKey,"::","/") & ".html"
  End Function

  Private Function checkFile(byref fname)
    fname = Server.Mappath(DBPath & getPath())
    checkFile = fso.fileexists(fname)
  End Function

  Private Sub createPathName(byval idxKey)
    Dim TmpPa
    TmpPa = Server.Mappath(DBPath & idxKey)
    if not fso.folderexists(TmpPa) then
      if instr(idxKey,"\") > 0 then Call createPathName(left(idxKey,instrrev(idxKey,"\")-1))
      fso.createfolder(TmpPa)
    end if
  End Sub

  Public Function getTxt()
    if checkFile(fname) then
      set Txt = fso.getfile(fname)
      if Txt.size = 0 then
        Tmp = ""
      else
        Tmp = fso.opentextfile(fname).readall
      end if
      set Txt = Nothing
      getTxt = Tmp
    else
      getTxt = ""
    end if
  End Function

  Public Function remove()
    if checkFile(fname) then
      fso.deletefile fname
    end if
  End Function

  Public Function Save(byval content)
    if checkFile(fname) then
      set fpo = fso.opentextfile(fname,2)
    else
      idxKey = replace(idxKey,"::","\")
      if instr(idxKey,"\")>0 then Call createPathName(left(idxKey,instrrev(idxKey,"\")-1))
      set fpo = fso.createtextfile(fname)
    end if
    fpo.write content
    fpo.close
    set fpo = nothing
  End Function
End Class

因为时间比较紧,而且代码比较简单,就不加注释了,实际就是简化了文本文件的操作方法。

<% Server.ScriptTimeOut=10000 %> 
<%
  '数据库链接代码
  
  set fdb = new FileDB
  fdb.DBPath = "../DataCenter/sms_DB/"
    
  conn.open constr
  set rs = server.createobject("ADODB.Recordset")
  '得到所有没有转换的数据
  rs.open "select * from sendlog where send_mob not like '%::%'",conn,3,2
  do while not rs.eof
    'FileDB 数据存放路径,日期::MD5(ID)
    idxStr = split(Rs("send_date")," ")(0) & "::" & md5(Rs("send_id"))
    fdb.IdxKey = idxStr
    fdb.Save(Rs("send_mob"))
    Rs("send_mob") = idxStr
    rs.update
    rs.movenext
  loop
  rs.close
  conn.close
  
  '数据库压缩过程,不是重点,再次不再多述
  compactdata(DataPath)
%>
减肥成功,所有数据转存到FileDB中。

执行一下,所有数据就转存好了,读取的时候很简单,指定了 idxStr,用getTxt()即可得到内容。

  set fdb = new FileDB
  fdb.DBPath = "../DataCenter/sms_DB/"
  '../DataCenter/sms_DB/aaa/1111.txt
  fdb.idxKey = "aaa::1111"
  str1 = fdb.getTxt()
  '../DataCenter/sms_DB/bbb/ccc/ddd/eee.txt
  fdb.idxKey = "bbb:ccc::ddd:eee"
  str2 = fdb.getTxt()
  '删除 ../DataCenter/sms_DB/bbb/ccc/ddd/eee.txt
  fdb.remove() 
  '因为文件不存在,得到的值就是空字符串
  str3 = fdb.getTxt()
  '将内容保存到../DataCenter/sms_DB/bbb/ccc/ddd/eee.txt,因为不存在则创建,如果存在,则修改。
  fdb.save("11111")

2010年10月24日更新小Bug,修复了idxKey 定于数据存放在根目录,就会报错的错误