用 AutoHotkey 实现Vim和Excel的数据传递

应用场景是Excel某N列数据想用Vim处理后再复制回Excel。

Vim提供了ole接口供其他语言调用,详见:h ole.txt

  一、Excel内容转到Vim新缓冲区

首先获取Excel选中区域的内容

rng := ComObjActive("Excel.application").selection

  下面是两个函数:

  1. 激活Vim并保证当前是新缓冲区
  2. 把Excel的arrV写到Vim新缓冲区
GVim_newBuffer() ;打开新缓冲区
{
    if ProcessExist("gvim.exe")
    {
        WinShow("ahk_class Vim")
        WinActivate("ahk_class Vim")
        oVim := ComObjActive("Vim.application")
        if oVim.eval('strlen(join(getline(1,"$"),"\r\n"))') ;如果是两个空行也认为不是空缓冲区
            oVim.eval('execute("$tabnew")')
    }
    else
{ run("d:\soft\Vim\gvim.exe") ;替换成自己的gvim.exe路径
WinWait("ahk_class Vim")
} } ;arrV可以是字符串 GVim_setBuffer(arrV) { oVim := ComObjActive("Vim.application") if IsObject(arrV) { loop(arrV.MaxIndex(1)) { r := A_Index sRow := "" loop(arrV.MaxIndex(2)) sRow .= arrV[r,A_Index].delete0() . A_Tab oVim.eval(format('setline({1},iconv("{2}","cp936","utf-8"))',r,RTrim(sRow,A_Tab))) } } else ;字符串 oVim.eval(format('setline(1,iconv("{1}","cp936","utf-8"))',arrV))
  oVim.SendKeys('gg') ;顺便刷新Vim }

  然后整体的调用代码:

rng := ComObjActive("Excel.application").selection
GVim_newBuffer()
if (rng.cells.count = 1)
    GVim_setBuffer(rng.value)
else
    GVim_setBuffer(rng.value)
WinActivate("ahk_class Vim")

二、从Vim缓冲区内容转到Excel

 用如下命令就能获取Vim当前缓冲区的内容(字符串格式),需要用iconv来转换编码供ahk使用。

oVim := ComObjActive("Vim.application")
rs := oVim.eval('line("$")') ;行数
str := oVim.eval('iconv(join(getline(1,"$"),"\r\n"),"utf-8","cp936")')

对str的第一行内容用tab分割就知道有几列数据了(如果后面列数比第1行多就会报错了,可以多设置列数)

loop parse, str, "`n", "`r"
{
    cs := StrSplit(A_LoopField, A_Tab).length()
    break
}

  然后就可以用ComObjArray把字符串转成数组,再写入Excel的selection即可

arrA := ComObjArray(12, rs, cs)
loop parse, str, "`n", "`r"
{
    r := A_Index-1
    for k, v in StrSplit(A_LoopField, A_Tab)
        arrA[r,k-1] := v
}
ComObjActive("Excel.application").selection.cells(1).value := arrA
posted @ 2019-08-08 00:20  火冷  阅读(1216)  评论(1编辑  收藏  举报