用AutoHotkey实现 iThoughts 思维导图节点文本一键转到Excel

iThoughts 复制节点,获取数据的格式是:

11
    21
    22
        31
        32
12

目的是转成Excel的表格格式:

11 21
11 22 31
11 22 32
12

核心就是用 AutoHotkey 实现字符串的转换,

并把数据转为 Excel 识别的数组 arrA,

再用 vba 把 arrA写入当前单元格即可

F9::
clipboard := ""
send("{ctrl down}c{ctrl up}")
if !ClipWait(1)
    return
arrA := indent2table(clipboard, true)
;根据 arrA 的尺寸获取 Excel 表对应的区域 rng
rng := ComObjActive("Excel.application").ActiveCell.resize(arrA.MaxIndex(1)+1,arrA.MaxIndex(2)+1)
;rng.NumberFormat := "@"
rng.value := arrA
rng.EntireColumn.AutoFit() ;自动列宽
WinActivate("ahk_class XLMAIN")
return

indent2table(strAll, toArrayA:=false)
{
    cnt := 4 ;每级空格的数量
    arrLine := [] ;这是临时的,匹配完整一行后才会添加到arrRes
    arrRes := [] ;结果,每项为数组
    cs := 0 ;最大列号
    loop parse, strAll, "`n", "`r"
    {
        ;过滤空行
        if !strlen(trim(A_LoopField))
            continue
        ;去掉右边的空白
        sLine := rtrim(A_LoopField)
        ;行首有空白字符
        if (sLine ~= "^\s")
        {
            ;获取等级(没空白为1)
            level := ((strlen(sLine) - strlen(ltrim(sLine))) // cnt) + 1
            ;清空左空白
            sLine := ltrim(sLine)
            ;NOTE 处理逻辑
            lenLast := arrLine.length()
            if (level == lenLast + 1) ;上一行的下级
                arrLine.push(sLine)
            else
            {
                ;添加结果并记录最大列号 cs NOTE 用 clone
                arrRes.push(arrLine.clone())
                if (arrLine.length() > cs)
                    cs := arrLine.length()
                ;设置 arrLine[level]
                arrLine[level] := sLine
                ;清空 arrLine[level] 及后面的内容
                if (lenLast > level)
                {
                    loop(lenLast - level)
                        arrLine.pop()
                }
            }
        }
        else ;第1级
        {
            ;添加结果并记录最大列号 cs
            if arrLine.length()
            {
                arrRes.push(arrLine.clone())
                if (arrLine.length() > cs)
                    cs := arrLine.length()
            }
            ;重置 arrLine
            arrLine := [sLine]
        }
    }
    ;添加最后一个结果
    arrRes.push(arrLine)
    if !toArrayA
        return arrRes
    ;转成 arrayA 供Excel写入
    rs := arrRes.length()
    arrA := ComObjArray(12, rs, cs)
    loop(rs)
    {
        r := A_Index
        for _, v in arrRes[r]
            arrA[r-1,A_Index-1] := v
    }
    return arrA
}
posted @ 2020-05-02 22:28  火冷  阅读(576)  评论(0编辑  收藏  举报