;duplicate top10 src = ( 加 就 加 加 加 的 到 否 的 额 一 他 个 飞 的 的 他 的 对 额 额 他 哦 平 去 我 额 人 啊 是 的 飞 个 好 ) a := [] b = loop, Parse, src, `n, `r { if !a["" A_LoopField] a["" A_LoopField] := 1 else a["" A_LoopField] += 1 } for c,d in a { d2 := SubStr("00000", 1, 5-strlen(d)) d str := d2 "_" c b .= b ? "`n" str : str } Sort, b, R e := StrSplit(b,"`n","`r") f = loop 10 f .= f ? "`n" e[A_index] : e[A_index] MsgBox % f
MD5 16位是32位截取的
SubStr(md5,9,16)
HashFromAddr(pData, len, algid, key=0) { hProv := size := hHash := hash := "" ptr := (A_PtrSize) ? "ptr" : "uint" aw := (A_IsUnicode) ? "W" : "A" if (DllCall("advapi32\CryptAcquireContext" aw, ptr "*", hProv, ptr, 0, ptr, 0, "uint", 1, "uint", 0xF0000000)) { if (DllCall("advapi32\CryptCreateHash", ptr, hProv, "uint", algid, "uint", key, "uint", 0, ptr "*", hHash)) { if (DllCall("advapi32\CryptHashData", ptr, hHash, ptr, pData, "uint", len, "uint", 0)) { if (DllCall("advapi32\CryptGetHashParam", ptr, hHash, "uint", 2, ptr, 0, "uint*", size, "uint", 0)) { VarSetCapacity(bhash, size, 0) DllCall("advapi32\CryptGetHashParam", ptr, hHash, "uint", 2, ptr, &bhash, "uint*", size, "uint", 0) } } DllCall("advapi32\CryptDestroyHash", ptr, hHash) } DllCall("advapi32\CryptReleaseContext", ptr, hProv, "uint", 0) } int := A_FormatInteger SetFormat, Integer, h Loop, % size { v := substr(NumGet(bhash, A_Index-1, "uchar") "", 3) while (strlen(v)<2) v := "0" v hash .= v } SetFormat, Integer, % int return hash } HashFromString(string, algid, key=0) { len := strlen(string) if (A_IsUnicode) { ;VarSetCapacity(data, len) ;StrPut(string, &data, len, "cp0") return HashFromAddr(&data, len, algid, key) } data := string return HashFromAddr(&data, len, algid, key) } MD5(string,b16:=false) { ;0x8003/*_CALG_MD5*/ ;0x8001/*_CALG_MD2*/ ;0x8002/*_CALG_MD4*/ ;0x8004/*_CALG_SHA1*/ return b16 ? SubStr(HashFromString(string, 0x8003),9,16) : HashFromString(string, 0x8003) } MsgBox % md5(Ansi2UTF8("我们"),1)
/* ;示例 dd := new DD() ;鼠标绝对移动 dd.mov(500,500) ;按键 dd.key(401) ;输入文字 str = Autohotkey loop % strlen(str) dd.str(SubStr(str,A_index,1)) */ class DD { __New() { ;加载DD 32位 dll 请重命名成DD.dll放到脚本目录 IfNotExist, DD.dll { RegRead, dd_path, HKLM, SOFTWARE\DD XOFT, path if !dd_path { MsgBox, 4112, 错误, DD.dll未找到! return } else { this.hModule := DllCall("LoadLibrary", "Str", dd_path, "Ptr") } } else { this.hModule := DllCall("LoadLibrary", "Str", "DD.dll", "Ptr") } } __Delete() { DllCall("FreeLibrary", "Ptr", this.hModule) } btn(btn) ;鼠标按键 { return DllCall("DD\DD_btn","Int",btn) } mov(x,y) ;鼠标绝对移动 { return DllCall("DD\DD_mov","Int",x,"Int",y) } movR(dx,dy) ;鼠标相对移动 { return DllCall("DD\DD_movR","Int",dx,"Int",dy) } key(key,flag) ;键盘按键 key:DD专用虚拟键码 flag:按下=1,放开=2 { return DllCall("DD\DD_key","Int",key,"Int",flag) } whl(flag) ;鼠标滚轮 按下=1,放开=2 { return DllCall("DD\DD_whl","Int",flag) } str(str) ;直接输入键盘上的可见字符 { return DllCall("DD\DD_str","Ptr",&str) } todc(vkcode) ;虚拟键码转DD键码 { return DllCall("DD\DD_todc","Int",vkcode) } MouseMove(hwnd,x,y) ;窗口内鼠标移动 hwnd:窗口句柄,为0时表示全屏,等同mov { return DllCall("DD\DD_MouseMove","Int",hwnd,"Int",x,"Int",y) } SnapPic(hwnd,x,y,w,h) ;抓图 hwnd:窗口句柄,为0时表示全屏 暂时无法使用 { return DllCall("DD\DD_SnapPic","Int",hwnd,"Int",x,"Int",y,"Int",w,"Int",h) } PickColor(hwnd,x,y,const:=0) ;窗口内取色 hwnd:窗口句柄,为0时表示全屏 const:常量始终等于0 暂时无法使用 { return DllCall("DD\DD_PickColor","Int",hwnd,"Int",x,"Int",y,"Int",const) } GetActiveWindow() ;取激活窗口句柄 用普通方法无法获取时可用这个函数 暂时无法使用 { return DllCall("DD\DD_GetActiveWindow") } }
;预配置项 url_l = http://www.a67.com/list/1/7/p. id = 1 ;初始页码 maxid = 129 ;最大页码 url_r = site = http://www.a67.com kind = 动作片 #Include sqliteDB.ahk #NoEnv OnExit, Exit ;初始化连接数据库 以便反复查询 DBFileName := A_ScriptDir . "\a67.db" global DB DB := new SQLiteDB if !DB.OpenDB(DBFileName) { MsgBox, 16, SQLite错误, % "消息:`t" . DB.ErrorMsg . "`n代码:`t" . DB.ErrorCode ExitApp } ;首先检查初始化 if !IsObject(Query("select 1 from sqlite_master where name='movie'")) ;检查novel表 Exec("CREATE TABLE ""movie"" ( ""name"" TEXT(255), ""kind"" TEXT(255), ""uri"" TEXT(255),id"" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)") Loop % maxid-id { list := URLDownloadToVar(url_l id url_r,"utf-8") ;抓取小说列表 a := StrSplit(list,"`n","`r") ;分割行为数组 a_id = 283 ;直接跳到正文 Loop { a_id++ if (a_id>a.MaxIndex()) break ;抓取影片信息 if (RegExMatch(a[a_id],"^<a href=""(http://www\.a67\.com/movie/\d+)""[^>]*>([^<]*)</a>$",b)) { page:=b1,name:=b2,movie_id:=RegExReplace(b1,"http://www\.a67\.com/movie/(\d+)$","$1") ToolTip % name "," movie_id "," page a_id++ t_page := URLDownloadToVar(page,"utf-8") IfInString, t_page, cqmp4 uri = cqmp4 else ifInString, t_page, hdmp4 uri = hdmp4 else ifInString, t_page, mp4-g.gif uri = mp4 else continue t_down := URLDownloadToVar("http://www.a67.com/down/1_" movie_id "_1/" uri,"utf-8") ;获取下载页的下载地址 IfInString, t_down, 404.gif continue d := StrSplit(t_down,"`n","`r") Loop % d.MaxIndex() { if RegExMatch(d[A_Index],"^\s*.*(thunder://[^""]*)"".*迅雷下载</a></li>",e) { url:=e1 ToolTip % id "页:" name Exec("Insert INTO ""movie"" (""name"", ""kind"", ""uri"") VALUES ('" name "','" kind "','" url "')") ;插入数据 break } } } } id++ } MsgBox, Ok #z:: exit: DB.CloseDB() DB = ExitApp URLDownloadToVar(url, Encoding = "",Method="GET",postData=""){ ;网址,编码,请求方式,post数据 hObject:=ComObjCreate("WinHttp.WinHttpRequest.5.1") if Method = GET { Try { hObject.Open("GET",url) hObject.Send() } catch e return -1 } else if Method = POST { Try { hObject.Open("POST",url,False) hObject.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded") hObject.Send(postData) } catch e return -1 } if (Encoding && hObject.ResponseBody) { oADO := ComObjCreate("adodb.stream") oADO.Type := 1 oADO.Mode := 3 oADO.Open() oADO.Write(hObject.ResponseBody) oADO.Position := 0 oADO.Type := 2 oADO.Charset := Encoding return oADO.ReadText(), oADO.Close() } return hObject.ResponseText } ;构造查询SQL函数 Query(SQL){ ;返回数组 global DB ;全局 if !DB.GetTable(SQL, Result) MsgBox, 16, SQLite错误: 获取结果, % "消息:`t" . DB.ErrorMsg . "`n代码:`t" . DB.ErrorCode "`n" SQL if (Result.HasRows) { return Result.Rows } } ;构造执行SQL函数 Exec(SQL){ ;返回执行影响行数 global DB ;全局 if !DB.Exec(SQL) MsgBox, 16, SQLite错误: 获取结果, % "消息:`t" . DB.ErrorMsg . "`n代码:`t" . DB.ErrorCode "`n" SQL return DB._Changes() }
decodeu(ustr){ Loop { if !ustr break if RegExMatch(ustr,"^\s*\\u([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})(.*)",m) { word_u := Chr("0x" m2) Chr("0x" m1), ustr := m3, word_a := "" Unicode2Ansi(word_u,word_a,0) out .= word_a } else if RegExMatch(ustr, "^([a-zA-Z0-9\.\?\-\!\s]*)(.*)",n) { ustr := n2 out .= n1 } } return out } Unicode2Ansi(ByRef wString, ByRef sString, CP = 0) { nSize := DllCall("WideCharToMultiByte" , "Uint", CP , "Uint", 0 , "Uint", &wString , "int", -1 , "Uint", 0 , "int", 0 , "Uint", 0 , "Uint", 0) VarSetCapacity(sString, nSize) DllCall("WideCharToMultiByte" , "Uint", CP , "Uint", 0 , "Uint", &wString , "int", -1 , "str", sString , "int", nSize , "Uint", 0 , "Uint", 0) }
Gui, Add, text, x0 y0 w400 h20, 要翻译的文字 Gui, Add, edit, x0 y20 w400 h180 vsrc Gui, Add, text, x400 y0 w400 h20, 结果 Gui, Add, Edit, x400 y20 w400 h180 vdst gui, Add, Button, x0 y200 w800 h20 gtrans, 翻译 gui, Show, , 翻译测试 return trans: Gui, Submit, NoHide url := "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc" post := "type=AUTO&i=" encodeURIComponent(src) "&doctype=json&xmlVersion=1.8&keyfrom=fanyi.web&ue=UTF-8&action=FY_BY_CLICKBUTTON&typoResult=true" json := URLDownloadToVar(url,"UTF-8","POST",post) obj := json_toobj(json) if (obj.errorcode="0") { dst := obj.translateResult.1.1.tgt a := obj.smartResult.entries for k,v in a dst .= "`n" (A_Index=1 ? "智能翻译:" : Ceil(A_index-1) "." v) GuiControl, , dst, % dst } else GuiControl, , dst, % obj.errorcode return GuiClose: ExitApp json_toobj(str){ quot := """" ws := "`t`n`r " Chr(160) obj := {} objs := [] keys := [] isarrays := [] literals := [] y := nest := 0 StringGetPos, z, str, %quot% while !ErrorLevel { StringGetPos, x, str, %quot%,, % z + 1 while !ErrorLevel { StringMid, key, str, z + 2, x - z - 1 StringReplace, key, key, \\, \u005C, A If SubStr( key, 0 ) != "\" Break StringGetPos, x, str, %quot%,, % x + 1 } str := ( z ? SubStr( str, 1, z ) : "" ) quot SubStr( str, x + 2 ) StringReplace, key, key, \%quot%, %quot%, A StringReplace, key, key, \b, % Chr(08), A StringReplace, key, key, \t, % A_Tab, A StringReplace, key, key, \n, `n, A StringReplace, key, key, \f, % Chr(12), A StringReplace, key, key, \r, `r, A StringReplace, key, key, \/, /, A while y := InStr( key, "\u", 0, y + 1 ) if ( A_IsUnicode || Abs( "0x" SubStr( key, y + 2, 4 ) ) < 0x100 ) key := ( y = 1 ? "" : SubStr( key, 1, y - 1 ) ) Chr( "0x" SubStr( key, y + 2, 4 ) ) SubStr( key, y + 6 ) literals.insert(key) StringGetPos, z, str, %quot%,, % z + 1 } key := isarray := 1 Loop Parse, str, % "]}" { StringReplace, str, A_LoopField, [, [], A Loop Parse, str, % "[{" { if ( A_Index != 1 ) { objs.insert( obj ) isarrays.insert( isarray ) keys.insert( key ) obj := {} isarray := key := Asc( A_LoopField ) = 93 } if ( isarray ) { Loop Parse, A_LoopField, `,, % ws "]" if ( A_LoopField != "" ) obj[key++] := A_LoopField = quot ? literals.remove(1) : A_LoopField } else { Loop Parse, A_LoopField, `, Loop Parse, A_LoopField, :, % ws if ( A_Index = 1 ) key := A_LoopField = quot ? literals.remove(1) : A_LoopField else if ( A_Index = 2 && A_LoopField != "" ) obj[key] := A_LoopField = quot ? literals.remove(1) : A_LoopField } nest += A_Index > 1 } If !--nest Break pbj := obj obj := objs.remove() obj[key := keys.remove()] := pbj If ( isarray := isarrays.remove() ) key++ } Return obj } encodeURIComponent(p) { str:=Ansi2UTF8(p) res:=Encode(&str) return res } Encode(p) { SetFormat,integer,hex res := "" while,value := *p++ { if(value==33 || (value>=39 && value <=42) || value==45 || value ==46 || (value>=48 && value<=57) || (value>=65 && value<=90) || value==95 || (value>=97 && value<=122) || value==126) res .= Chr(value) Else { res .= "%" res .= SubStr(value,3,2) } } Return res } Ansi2UTF8(sString) { Ansi2Unicode(sString, wString, 0) Unicode2Ansi(wString, zString, 65001) Return zString } UTF82Ansi(zString) { Ansi2Unicode(zString, wString, 65001) Unicode2Ansi(wString, sString, 0) Return sString } Ansi2Unicode(ByRef sString, ByRef wString, CP = 0) { nSize := DllCall("MultiByteToWideChar" , "Uint", CP , "Uint", 0 , "Uint", &sString , "int", -1 , "Uint", 0 , "int", 0) VarSetCapacity(wString, nSize * 2) DllCall("MultiByteToWideChar" , "Uint", CP , "Uint", 0 , "Uint", &sString , "int", -1 , "Uint", &wString , "int", nSize) } Unicode2Ansi(ByRef wString, ByRef sString, CP = 0) { nSize := DllCall("WideCharToMultiByte" , "Uint", CP , "Uint", 0 , "Uint", &wString , "int", -1 , "Uint", 0 , "int", 0 , "Uint", 0 , "Uint", 0) VarSetCapacity(sString, nSize) DllCall("WideCharToMultiByte" , "Uint", CP , "Uint", 0 , "Uint", &wString , "int", -1 , "str", sString , "int", nSize , "Uint", 0 , "Uint", 0) } URLDownloadToVar(url, Encoding = "",Method="GET",postData=""){ ;网址,编码,请求方式,post数据 hObject:=ComObjCreate("WinHttp.WinHttpRequest.5.1") if Method = GET { hObject.Open("GET",url) Try hObject.Send() catch e return -1 } else if Method = POST { hObject.Open("POST",url,False) hObject.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded") Try hObject.Send(postData) catch e return -1 } if Encoding { oADO := ComObjCreate("adodb.stream") oADO.Type := 1 oADO.Mode := 3 oADO.Open() oADO.Write(hObject.ResponseBody) oADO.Position := 0 oADO.Type := 2 oADO.Charset := Encoding return oADO.ReadText(), oADO.Close() } return hObject.ResponseText }
Gui, Add, text, x0 y0 w400 h20, 要翻译的文字 Gui, Add, edit, x0 y20 w400 h180 vsrc Gui, Add, text, x400 y0 w400 h20, 结果 Gui, Add, Edit, x400 y20 w400 h180 vdst gui, Add, Button, x0 y200 w800 h20 gtrans vtrans, 翻译 gui, Show, , 百度翻译测试 return trans: Gui, Submit, NoHide GuiControl, Disable, trans url := "http://fanyi.baidu.com/v2transapi" if RegExMatch(src,"[^a-zA-Z0-9\.\?\-\!\s]") slang := "zh",dlang := "en" else slang := "en",dlang := "zh" post := "from=" slang "&to=" dlang "&query=" encodeURIComponent(src) "&transtype=realtime&simple_means_flag=3" json := URLDownloadToVar(url,"UTF-8","POST",post) obj := json_toobj(json) trans_result := decodeu(obj.trans_result.data.1.dst) res := "翻译结果:`n" trans_result "`n`n" dict_result := obj.dict_result.simple_means.symbols if IsObject(dict_result.1) { res .= "词典结果:`n" for k,v in dict_result.1.parts { res .= k ". " v.part if IsObject(v.means) { for x,y in v.means { if IsObject(y) res .= decodeu(y.word_mean) ";" else res .= decodeu(y) ";" } res .= "`n" } } } if IsObject(obj.dict_result.cizu) { res .= "`n词组结果:`n" for k,v in obj.dict_result.cizu res .= k ". " decodeu(v.fanyi) "(" decodeu(v.cz_name) "):" v.jx.1.jx_en " " decodeu(v.jx.1.jx_zh) "`n" } GuiControl, , dst, % res GuiControl, Enable, trans return GuiClose: ExitApp json_toobj(str){ quot := """" ws := "`t`n`r " Chr(160) obj := {} objs := [] keys := [] isarrays := [] literals := [] y := nest := 0 StringGetPos, z, str, %quot% while !ErrorLevel { StringGetPos, x, str, %quot%,, % z + 1 while !ErrorLevel { StringMid, key, str, z + 2, x - z - 1 StringReplace, key, key, \\, \u005C, A If SubStr( key, 0 ) != "\" Break StringGetPos, x, str, %quot%,, % x + 1 } str := ( z ? SubStr( str, 1, z ) : "" ) quot SubStr( str, x + 2 ) StringReplace, key, key, \%quot%, %quot%, A StringReplace, key, key, \b, % Chr(08), A StringReplace, key, key, \t, % A_Tab, A StringReplace, key, key, \n, `n, A StringReplace, key, key, \f, % Chr(12), A StringReplace, key, key, \r, `r, A StringReplace, key, key, \/, /, A while y := InStr( key, "\u", 0, y + 1 ) if ( A_IsUnicode || Abs( "0x" SubStr( key, y + 2, 4 ) ) < 0x100 ) key := ( y = 1 ? "" : SubStr( key, 1, y - 1 ) ) Chr( "0x" SubStr( key, y + 2, 4 ) ) SubStr( key, y + 6 ) literals.insert(key) StringGetPos, z, str, %quot%,, % z + 1 } key := isarray := 1 Loop Parse, str, % "]}" { StringReplace, str, A_LoopField, [, [], A Loop Parse, str, % "[{" { if ( A_Index != 1 ) { objs.insert( obj ) isarrays.insert( isarray ) keys.insert( key ) obj := {} isarray := key := Asc( A_LoopField ) = 93 } if ( isarray ) { Loop Parse, A_LoopField, `,, % ws "]" if ( A_LoopField != "" ) obj[key++] := A_LoopField = quot ? literals.remove(1) : A_LoopField } else { Loop Parse, A_LoopField, `, Loop Parse, A_LoopField, :, % ws if ( A_Index = 1 ) key := A_LoopField = quot ? literals.remove(1) : A_LoopField else if ( A_Index = 2 && A_LoopField != "" ) obj[key] := A_LoopField = quot ? literals.remove(1) : A_LoopField } nest += A_Index > 1 } If !--nest Break pbj := obj obj := objs.remove() obj[key := keys.remove()] := pbj If ( isarray := isarrays.remove() ) key++ } Return obj } decodeu(ustr){ Loop { if !ustr break if RegExMatch(ustr,"^\s*\\u([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})(.*)",m) { word_u := Chr("0x" m2) Chr("0x" m1), ustr := m3, word_a := "" Unicode2Ansi(word_u,word_a,0) out .= word_a } else if RegExMatch(ustr, "^([a-zA-Z0-9\.\?\-\!\s]*)(.*)",n) { ustr := n2 out .= n1 } } return out } encodeURIComponent(p) { str:=Ansi2UTF8(p) res:=Encode(&str) return res } Encode(p) { SetFormat,integer,hex res := "" while,value := *p++ { if(value==33 || (value>=39 && value <=42) || value==45 || value ==46 || (value>=48 && value<=57) || (value>=65 && value<=90) || value==95 || (value>=97 && value<=122) || value==126) res .= Chr(value) Else { res .= "%" res .= SubStr(value,3,2) } } SetFormat,integer, d Return res } Ansi2UTF8(sString) { Ansi2Unicode(sString, wString, 0) Unicode2Ansi(wString, zString, 65001) Return zString } UTF82Ansi(zString) { Ansi2Unicode(zString, wString, 65001) Unicode2Ansi(wString, sString, 0) Return sString } Ansi2Unicode(ByRef sString, ByRef wString, CP = 0) { nSize := DllCall("MultiByteToWideChar" , "Uint", CP , "Uint", 0 , "Uint", &sString , "int", -1 , "Uint", 0 , "int", 0) VarSetCapacity(wString, nSize * 2) DllCall("MultiByteToWideChar" , "Uint", CP , "Uint", 0 , "Uint", &sString , "int", -1 , "Uint", &wString , "int", nSize) } Unicode2Ansi(ByRef wString, ByRef sString, CP = 0) { nSize := DllCall("WideCharToMultiByte" , "Uint", CP , "Uint", 0 , "Uint", &wString , "int", -1 , "Uint", 0 , "int", 0 , "Uint", 0 , "Uint", 0) VarSetCapacity(sString, nSize) DllCall("WideCharToMultiByte" , "Uint", CP , "Uint", 0 , "Uint", &wString , "int", -1 , "str", sString , "int", nSize , "Uint", 0 , "Uint", 0) } URLDownloadToVar(url, Encoding = "",Method="GET",postData=""){ hObject:=ComObjCreate("WinHttp.WinHttpRequest.5.1") if Method = GET { hObject.Open("GET",url) Try hObject.Send() catch e return -1 } else if Method = POST { hObject.Open("POST",url,False) hObject.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8") hObject.SetRequestHeader("Accept", "*/*") hObject.SetRequestHeader("Referer", "http://fanyi.baidu.com/") hObject.SetRequestHeader("X-Requested-With", "XMLHttpRequest") Try hObject.Send(postData) catch e return -1 } if Encoding { oADO := ComObjCreate("adodb.stream") oADO.Type := 1 oADO.Mode := 3 oADO.Open() oADO.Write(hObject.ResponseBody) oADO.Position := 0 oADO.Type := 2 oADO.Charset := Encoding return oADO.ReadText(), oADO.Close() } return hObject.ResponseText }
var_dump(obj,level:=0){ static id,str id++ if id=1 str := "" if IsObject(obj) { space = loop % level space .= A_Tab str .= space "{`n" for k,v in obj { if IsObject(v) { str .= space A_Tab (RegExMatch(k,"^\d+$") ? k : """" k """") ":`n" var_dump(v,level+1) str := RegExReplace(str,"(*ANYCRLF)\n$",",`n") } else str .= space A_Tab (RegExMatch(k,"^\d+$") ? k : """" k """") ":""" RegExReplace(v,"""","""""") """,`n" } str := RegExReplace(str,"(*ANYCRLF),\n*$","`n") str .= space "}`n" } else str := obj return str }
效果:
d := {"a":"animal","b":"bus","c":"cartoon","d":["door","desk","dream"]} Clipboard := var_dump(d) ;=> { "a":"animal", "b":"bus", "c":"cartoon", "d": { 1:"door", 2:"desk", 3:"dream" } }
;Thinkai@2015-10-27 ;本脚本需要安装office 2007 如果需要在仅有2003条件下运行,请替换323行注释掉的连接字串并替换.xlsx后缀 Gui, main:Add, button, x0 y0 w100 h20 gaddtab, 添加表格数据源 gui, main:add, Button, x100 y0 w100 h20 gsetto, 设置收件人信息 gui, main:add, Button, x200 y0 w100 h20 gsetfrom, 设置发件人信息 gui, main:add, Button, x300 y0 w100 h20 gsend, 开始发送 gui, main:add, Button, x400 y0 w100 h20 grl, 重新开始 ;gui, main:add, text, x0 y20 w100 h20, 发件人(可选) ;gui, main:add, Edit, x100 y20 w500 h20 vfrom gui, main:add, text, x0 y40 w100 h20, 标题前缀 gui, main:add, Edit, x100 y40 w500 h20 vtitle Gui, main:add,text, x0 y60 w600 h20, 正文 可用插入[delimiter]替换拆分字段信息 gui, main:add, Edit, x0 y80 w600 h100 vcontent gui, main:add, Progress, x0 y180 w600 h20 vprg, Gui, main:Add, ListView, x0 y200 w600 h300 vlv, 文件|Sheet|拆分依据字段|输出文件名前缀|目标Sheet Gui, main:Add, StatusBar, , 等待用户操作 Gui, main:show, , Excel数据拆分发邮件 Gui, main:Default ;调整、初始化信息 LV_ModifyCol(1,150) LV_ModifyCol(2,120) LV_ModifyCol(3,120) LV_ModifyCol(4,120) LV_ModifyCol(5,120) SB_SetParts(400,200) source := [] ;数据源数组 mailconfig:=[] ;发件人信息数组 IfExist config.ini ;读取发件人配置 { IniRead, setfrom_from, config.ini, from, from IniRead, setfrom_bcc, config.ini, from, bcc IniRead, setfrom_smtp, config.ini, from, smtp IniRead, setfrom_account, config.ini, from, account IniRead, setfrom_pass, config.ini, from, pass mailconfig.from:=setfrom_from,mailconfig.bcc:=setfrom_bcc,mailconfig.smtp:=setfrom_smtp,mailconfig.account:=setfrom_account,mailconfig.pass:=setfrom_pass } to_obj := [] IfExist, to.txt ;读取收件人名录 { FileRead, str, to.txt to_obj := getto(str) } return addtab: ;添加数据源 FileSelectFile, file, , , 选择一个表格, Excel文件(*.xls;*.xlsx) IfExist % file { SplitPath, file, , , , name ;获取文件名 source.insert({"name":name,"file":file,"sheets":{}}) SB_SetText("读取文件:" file) idx := source.maxindex() source[idx].db := new exceldb() ;创建excel adodb连接,获取数据表信息 source[idx].db.open(file) SB_SetText("读取文件:" file " 完毕!") sheet := source[idx].db.GetTableInfo() for k,v in sheet ;弹出若干个向导页设置数据源 { guide_fields := v SB_SetText("等待用户设置数据源") isguideok := false Gui, guide:Destroy Gui, guide:add, text, x0 y0 w100 h20, % "文件:" Gui, guide:add, text, x0 y20 w100 h20, % "Sheet:" Gui, guide:add, text, x100 y0 w300 h20, % guide_file:=file Gui, guide:add, text, x100 y20 w300 h20, % guide_sheet:=k f :="" ;,guide_sql:="CREATE TABLE [" k "] (" ;创建表语句 已废弃 for x,y in v { f .= f ? "|" y : y ;guide_sql .= y " TEXT," } ;StringTrimRight, guide_sql, guide_sql, 1 ;guide_sql .= ")" Gui, guide:add, text, x0 y40 w100 h20, 拆分依据字段: Gui, guide:add, DropDownList, x100 y40 w300 vguide_ddl, % f Gui, guide:add, text, x0 y60 w100 h20, 输出文件名前缀: Gui, guide:add, Edit, x100 y60 w300 h20 vguide_prefix, % name Gui, guide:add, text, x0 y80 w100 h20, 目标Sheet: Gui, guide:add, Edit, x100 y80 w300 h20 vguide_dstsheet, % k Gui, guide:add, Button, x0 y100 w200 h20 gconfirm, 确认 Gui, guide:add, Button, x200 y100 w200 h20 gjump, 跳过 Gui, guide:Show, , % "数据源导入向导——" name while(!isguideok) Sleep, 100 Gui, guide:Destroy SB_SetText("数据源设置完毕") } ;source[idx].db.close() ;不关闭连接。特别是对于一些大的07文件,在后续拆分情况下避免消耗无谓时间 } return rl: ;重载 Reload confirm: ;向导确认 Gui, guide:Submit, NoHide if !guide_ddl { MsgBox, 4112, 错误, 拆分依据字段不能为空! return } Gui, main:Default LV_Add("",guide_file,guide_sheet,guide_ddl,guide_prefix,guide_dstsheet) source[idx]["sheets"].insert({"fields":guide_fields,"sheet":guide_sheet,"delimiter":guide_ddl,"prefix":guide_prefix,"dstsheet":guide_dstsheet}) ;,"createsql":guide_sql isguideok := true return jump: ;向导跳过 isguideok := true return setto: ;设置收件人 IfExist, to.txt FileRead, to, to.txt Gui, setto:Destroy Gui, setto:Add, text, x0 y0 w600 h40, 在下方修改联系人信息。可从excel中粘贴过来,左边是拆分依据字段,右边联系人邮箱,多个用`"`,`"分隔`n例如:某某部门 xxx<xxx@xxx.com>`,`"xxx`"<xxx@xxx.com> (制表符分隔) Gui, setto:Add, Edit, x0 y40 w600 h400 vsetto_to, % to Gui, setto:Add, Button, x0 y440 w600 h20 gsetto_ok, 确定 Gui, setto:Show, , 设置收件人信息 return setto_ok: ;设置收件人完毕 GuiControlGet, setto_to FileDelete, to.txt FileAppend, % setto_to, to.txt to_obj := getto(setto_to) Gui, setto:Destroy return setfrom: ;设置发件人 IfExist config.ini { IniRead, setfrom_from, config.ini, from, from IniRead, setfrom_bcc, config.ini, from, bcc IniRead, setfrom_smtp, config.ini, from, smtp IniRead, setfrom_account, config.ini, from, account IniRead, setfrom_pass, config.ini, from, pass } Gui, setfrom:Destroy Gui, setfrom:add, text, x0 y0 w100 h20, 默认发件人* Gui, setfrom:add, Edit, x100 y0 w300 h20 vsetfrom_from, % setfrom_from ? setfrom_from : "某某<xxx@xxx.com>" Gui, setfrom:add, text, x0 y20 w100 h20, 默认暗送人 Gui, setfrom:add, Edit, x100 y20 w300 h20 vsetfrom_bcc, % setfrom_bcc ? setfrom_bcc : "某某<xxx@xxx.com>" Gui, setfrom:add, text, x0 y40 w100 h20, 发件邮箱smtp* Gui, setfrom:add, Edit, x100 y40 w300 h20 vsetfrom_smtp, % setfrom_smtp ? setfrom_smtp : "smtp.xxx.com" Gui, setfrom:add, text, x0 y60 w100 h20, 发件邮箱账号* Gui, setfrom:add, Edit, x100 y60 w300 h20 vsetfrom_account, % setfrom_account ? setfrom_account : "xxx@xxx.com" Gui, setfrom:add, text, x0 y80 w100 h20, 发件邮箱密码* Gui, setfrom:add, Edit, x100 y80 w300 h20 vsetfrom_pass, % setfrom_pass Gui, setfrom:add, Button ,x0 y100 w400 h20 gsetfrom_ok, 确定 Gui, setfrom:Show, , 设置发件人信息 return setfrom_ok: ;设置发件人完毕 Gui, setfrom:Submit, NoHide Gui, setfrom:Destroy IniWrite, % setfrom_from, config.ini, from, from IniWrite, % setfrom_bcc, config.ini, from, bcc IniWrite, % setfrom_smtp, config.ini, from, smtp IniWrite, % setfrom_account, config.ini, from, account IniWrite, % setfrom_pass, config.ini, from, pass mailconfig.from:=setfrom_from,mailconfig.bcc:=setfrom_bcc,mailconfig.smtp:=setfrom_smtp,mailconfig.account:=setfrom_account,mailconfig.pass:=setfrom_pass return send: ;开始拆分发送 Gui, main:Submit, NoHide SB_SetText("检查发件人信息") if ((!mailconfig.from && !from) || !mailconfig.smtp || !mailconfig.account || !mailconfig.pass) { MsgBox, 4112, 错误, 发件人信息未配置完整,请设置! return } GuiControl, main:, prg, 2 SB_SetText("检查收件人信息") if (to_obj.maxindex()=0) { MsgBox, 4112, 错误, 收件人信息未配置,请设置! return } GuiControl, main:, prg, 3 SB_SetText("检查标题信息") if !title { MsgBox, 4112, 错误, 标题未填写,请填写! return } GuiControl, main:, prg, 4 SB_SetText("创建临时目录") FileCreateDir, %A_ScriptDir%tmp FileDelete, %A_ScriptDir%tmp*.* GuiControl, main:, prg, 5 SB_SetText("创建模板文件") template := [] for a,b in source ;汇总要创建哪些模板文件 哪些sheet { sheets := b.sheets for c,d in sheets { if !IsObject(template[d.prefix]) template[d.prefix] := [] if !template[d.prefix][d.dstsheet] template[d.prefix][d.dstsheet] := {"file":b.file,"prefix":d.prefix,"fields":d.fields} } } GuiControl, main:, prg, 8 for e,f in template ;创建模板文件 { file := A_ScriptDir "tmp" e ".xlsx" g := new excel() ;新建Excel对象 g.open(file) for h,i in f { if A_Index > 3 ;如果超出默认的3个sheet g.conn.ActiveWorkbook.Sheets.Add g.conn.ActiveWorkbook.Sheets(A_index).Name := h ;重命名 g.setfields(A_index,i.fields) ;插入字段 g.save() ;保存 } g.close() } GuiControl, main:, prg, 15 attach := [] SB_SetText("输出Excel") for source_index,source_value in source ;遍历数据源 { SB_SetText(source_value.name) sheets := source_value.sheets ;遍历需要拆分的sheet if (source_value.sheets.maxindex() > 0) { for sheet_index,sheet_value in sheets { SB_SetText(source_value.name "`t "sheet_value.sheet) for delimiter in to_obj ;按拆分字段逐个拆分 { ;定义变量 if !IsObject(attach[delimiter]) attach[delimiter] := [] tmp_file := A_ScriptDir "tmp" guide_prefix "_" delimiter ".xlsx" template_file := A_ScriptDir "tmp" guide_prefix ".xlsx" FileCopy, % template_file, % tmp_file, 1 attach[delimiter].insert(tmp_file) SB_SetText(delimiter,2) tmp_result := source_value.db.GetTable("SELECT * FROM [" sheet_value.sheet "$] WHERE [" sheet_value.delimiter "]='" delimiter "';") ;读取拆分信息到数组 tmp_excel := new exceldb() tmp_excel.open(tmp_file) tmp_excel.conn.BeginTrans() for row,vaules in tmp_result { tmp_str := "" for k,v in vaules tmp_str .= tmp_str ? ",'" v "'" : "'" v "'" tmp_excel.conn.Execute("INSERT INTO [" sheet_value.dstsheet "$] VALUES (" tmp_str ")") ;插入语句 } tmp_excel.conn.CommitTrans() tmp_excel.close() } } } source_value.db.close() } GuiControl, main:, prg, 50 SB_SetText("发送邮件") for delimiter,attaches in attach { tmp_title := title "_" delimiter tmp_content := RegExReplace(content,"[delimiter]",delimiter) tmp_mail := to_obj[delimiter] SB_SetText("发送邮件:" tmp_title,2) SB_SetText(delimiter,2) Mail("",tmp_mail,tmp_title,tmp_content,attaches*) } GuiControl, main:, prg, 100 SB_SetText("发送完毕") return settoGuiClose: Gui, setto:Destroy return setfromGuiClose: Gui, setfrom:Destroy return guideGuiClose: return mainGuiClose: ExitApp getto(str){ o := [] Loop, Parse, str, `n, `r { IfInString, A_LoopField, `t { t := StrSplit(A_LoopField,"`t") o[t[1]] := t[2] } } return o } class exceldb { ;static conn __New() ;新建 { this.conn:= ComObjCreate("ADODB.connection") ;初始化COM } open(file) ;打开文件 { IfExist % file this.conn.Open("Provider=Microsoft.Ace.OLEDB.12.0;Extended Properties=Excel 12.0;Data Source=" file) ;打开连接 ;this.conn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties='Excel 8.0;HDR=Yes';Data Source=" file) ;打开连接 2003方式 } close() ;关闭文件 { this.conn.Close() } GetTableInfo() ;获取所有Sheet及字段信息 { ;通过OpenSchema方法获取表信息 rs := this.conn.OpenSchema(20) ;SchemaEnum 参考 http://www.w3school.com.cn/ado/app_schemaenum.asp t := [] rs.MoveFirst() while !rs.EOF { t_name := RegExReplace(rs.("TABLE_NAME").value,"$$","") q := this.conn.Execute("select top 1 * from [" t_name "$]") if (q.Fields(0).Name="F1" && q.Fields.Count=1) ;排除空表格 { rs.MoveNext() continue } t[t_name] := [] for field in q.Fields ;获取按顺序排列的字段 t[t_name].insert(field.Name) q.close() rs.MoveNext() } return t } GetTable(sql) { t := [] query := this.conn.Execute(sql) if RegExMatch(sql,"i)^select*") { fetchedArray := query.GetRows() ;取出数据(二维数组) colSize := fetchedArray.MaxIndex(1) + 1 ;列最大值 tips:从0开始 所以要+1 rowSize := fetchedArray.MaxIndex(2) + 1 ;行最大值 tips:从0开始 所以要+1 loop, % rowSize { i := (y := A_index) - 1 t[y] := [] loop, % colSize { j := (x := A_index) - 1 t[y][x] := fetchedArray[j,i] ;取出二维数组内值 } } query.Close() return t } } } class excel { ;static conn __New() ;新建 { this.conn:= ComObjCreate("Excel.Application") this.conn.Visible := false ;false } open(file) ;打开文件 { IfExist % file this.conn.Workbooks.Open(file) else { this.conn.Workbooks.Add this.conn.ActiveWorkbook.SaveAs(file) } } close() ;关闭文件 { this.conn.Workbooks.close() } sheets() ;获取所有Sheet { s := [] loop % this.conn.ActiveWorkbook.Sheets.Count s.insert(this.conn.ActiveWorkbook.Sheets(A_index).Name) return s } fields(sheet) ;获取指定sheet的字段 sheet为id或者具体名称 { c := [] loop % this.conn.ActiveWorkbook.Sheets(sheet).Columns.Count { try { x := this.conn.ActiveWorkbook.Sheets(sheet).Cells(1,A_index).Value if !x break c.insert(x) } catch e break } return c /* col_id := ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"] loop % this.conn.ActiveWorkbook.Sheets(sheet).Columns.Count { col := col_id[floor(A_index/26)] col_id[mod(A_index,26)] try { x:=excel.ActiveWorkbook.Sheets(sheet).Range(col "1").Value if !x break colname.insert(x) } catch e break } */ } setfields(sheet,fields) ;设置字段 即第一列信息 { return this.insertrow(sheet,1,fields) } setformat(sheet,range,format) ;设置某一区域的单元格格式 { this.conn.ActiveWorkbook.Sheets(sheet).Range(range).NumberFormat := format } insertrow(sheet,rowid,values) ;插入一列 { for k,v in values this.conn.ActiveWorkbook.Sheets(sheet).Cells(rowid,A_index).Value := v } save() { this.conn.ActiveWorkbook.Save() } } ;发邮件函数 参数 来自,发给,主题,html正文,附件若干 Mail(from,to,subject,content,attach*){ global mailconfig NameSpace := "http://schemas.microsoft.com/cdo/configuration/" Email := ComObjCreate("CDO.Message") Email.From := mailconfig.from Email.To := to if mailconfig.bcc Email.Bcc := mailconfig.bcc Email.Subject := subject ;Email.Htmlbody := content Email.Textbody := content for k,v in attach { IfExist, % v Email.AddAttachment(v) } Email.Configuration.Fields.Item(NameSpace "sendusing") := 2 Email.Configuration.Fields.Item(NameSpace "smtpserver") := mailconfig.smtp ;SMTP服务器地址 Email.Configuration.Fields.Item(NameSpace "smtpserverport") := 25 Email.Configuration.Fields.Item(NameSpace "smtpauthenticate") := 1 Email.Configuration.Fields.Item(NameSpace "sendusername") := mailconfig.account ;邮箱账号 Email.Configuration.Fields.Item(NameSpace "sendpassword") := mailconfig.pass ;邮箱密码 Email.Configuration.Fields.update Email.Send }
gui, add, text, x0 y0 w100 h20, 项目名 gui, add, edit, x100 y0 w200 h20 vname gui, add, text, x0 y20 w100 h20, 账户 gui, add, edit, x100 y20 w200 h20 vaccount Gui, add, Checkbox, x0 y40 w300 h20 vlog, 记录到数据库 gui, add, edit, x0 y60 w300 h20 vpass Gui, Add, Button, x0 y80 w300 h20 ggen, 生成密码 Gui, Show, , Thinkai的密码生成器 return gen: Gui, Submit, NoHide md5 := MD5(MD5(name) "@xx@" account) ;此处为算法 32位MD5 可以自己改 b:="" loop 14 ;此处做单数位大写处理 前十四位 { c := SubStr(md5,A_index,1) if (mod(A_index,2)=1) StringUpper, c, c b .= c } b .= "++" ;凑成16位 部分限制14位的比如百度就可以酌情复制 GuiControl, , pass, % Clipboard := b ;更新到结果框并复制到剪切板 if log ;此处通过途径记录到你的库里 或者写到文件里 URLDownloadToFile, http://xx.com/reg.php?name=%name%&account=%account%, %A_Temp%\xx.tmp return GuiClose: ExitApp MD5(string, encoding = "UTF-8") { return CalcStringHash(string, 0x8003, encoding) } CalcStringHash(string, algid, encoding = "UTF-8", byref hash = 0, byref hashlength = 0) { chrlength := (encoding = "CP1200" || encoding = "UTF-16") ? 2 : 1 length := (StrPut(string, encoding) - 1) * chrlength VarSetCapacity(data, length, 0) StrPut(string, &data, floor(length / chrlength), encoding) return CalcAddrHash(&data, length, algid, hash, hashlength) } CalcAddrHash(addr, length, algid, byref hash = 0, byref hashlength = 0) { static h := [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f"] static b := h.minIndex() hProv := hHash := o := "" if (DllCall("advapi32\CryptAcquireContext", "Ptr*", hProv, "Ptr", 0, "Ptr", 0, "UInt", 24, "UInt", 0xf0000000)) { if (DllCall("advapi32\CryptCreateHash", "Ptr", hProv, "UInt", algid, "UInt", 0, "UInt", 0, "Ptr*", hHash)) { if (DllCall("advapi32\CryptHashData", "Ptr", hHash, "Ptr", addr, "UInt", length, "UInt", 0)) { if (DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", 0, "UInt*", hashlength, "UInt", 0)) { VarSetCapacity(hash, hashlength, 0) if (DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", &hash, "UInt*", hashlength, "UInt", 0)) { loop % hashlength { v := NumGet(hash, A_Index - 1, "UChar") o .= h[(v >> 4) + b] h[(v & 0xf) + b] } } } } DllCall("advapi32\CryptDestroyHash", "Ptr", hHash) } DllCall("advapi32\CryptReleaseContext", "Ptr", hProv, "UInt", 0) } return o }
50 queries in 0.703 seconds |