AHK - 如何使用带条形码扫描器的动态热字符串

时间:2016-11-08 12:04:27

标签: regex autohotkey

当使用条形码扫描仪扫描产品的序列号时,我需要触发子程序。序列号如下所示:11NNNN22334。然后我需要使用扫描的序列号作为变量。

我尝试了下面包含的动态正则表达式热字符串库,但我无法使用条形码扫描器使其工作(它太快了)。我不想放慢条码扫描器的速度。它或者根本不触发子程序,或者在子程序被触发后留下序列号的第一个数字。有什么想法吗?

Test:
MsgBox, %$1% ; THIS IS THE STRING THAT TRIGGERED THE SUBROUTINE
return

hotstrings("([0-9][0-9]NNNN[0-9][0-9][0-9][0-9][0-9])", "Test")

/*
    Function: HotStrings
        Dynamically adds regular expression hotstrings.

    Parameters:
        c - regular expression hotstring
        a - (optional) text to replace hotstring with or a label to goto,
            leave blank to remove hotstring definition from triggering an action

    Examples:
> hotstrings("(B|b)tw\s", "%$1%y the way") ; type 'btw' followed by space, tab or return
> hotstrings("i)omg", "oh my god!") ; type 'OMG' in any case, upper, lower or mixed
> hotstrings("\bcolou?r", "rgb(128, 255, 0);") ; '\b' prevents matching with anything before the word, e.g. 'multicololoured'

    License:
        - RegEx Dynamic Hotstrings: Modified version by Edd  
        - Original: <http://www.autohotkey.net/~polyethene/#hotstrings>
        - Dedicated to the public domain (CC0 1.0) <http://creativecommons.org/publicdomain/zero/1.0/>
*/

hotstrings(k, a = "", Options:="")
{
    static z, m = "~$", m_ = "*~$", s, t, w = 2000, sd, d = "Left,Right,Up,Down,Home,End,RButton,LButton", f = "!,+,^,#", f_="{,}"
    global $
    If z = ; init
    {
        RegRead, sd, HKCU, Control Panel\International, sDecimal
        Loop, 94
        {
            c := Chr(A_Index + 32)
            If A_Index between 33 and 58
                Hotkey, %m_%%c%, __hs
            else If A_Index not between 65 and 90
                Hotkey, %m%%c%, __hs
        }
        e = 0,1,2,3,4,5,6,7,8,9,Dot,Div,Mult,Add,Sub,Enter
        Loop, Parse, e, `,
            Hotkey, %m%Numpad%A_LoopField%, __hs
        e = BS,Shift,Space,Enter,Return,Tab,%d%
        Loop, Parse, e, `,
            Hotkey, %m%%A_LoopField%, __hs
        z = 1
    }
    If (a == "" and k == "") ; poll
    {
        q:=RegExReplace(A_ThisHotkey, "\*\~\$(.*)", "$1")
        q:=RegExReplace(q, "\~\$(.*)", "$1")
        If q = BS
        {
            If (SubStr(s, 0) != "}")
                StringTrimRight, s, s, 1
        }
        Else If q in %d%
            s =
        Else
        {
            If q = Shift
            return
            Else If q = Space
                q := " "
            Else If q = Tab
                q := "`t"
            Else If q in Enter,Return,NumpadEnter
                q := "`n"
            Else If (RegExMatch(q, "Numpad(.+)", n))
            {
                q := n1 == "Div" ? "/" : n1 == "Mult" ? "*" : n1 == "Add" ? "+" : n1 == "Sub" ? "-" : n1 == "Dot" ? sd : ""
                If n1 is digit
                    q = %n1%
            }
            Else If (GetKeyState("Shift") ^ !GetKeyState("CapsLock", "T"))
                StringLower, q, q
            s .= q
        }
        Loop, Parse, t, `n ; check
        {
            StringSplit, x, A_LoopField, `r
            If (RegExMatch(s, x1 . "$", $)) ; match
            {
                StringLen, l, $
                StringTrimRight, s, s, l
                if !(x3~="i)\bNB\b")        ; if No Backspce "NB"
                    SendInput, {BS %l%}
                If (IsLabel(x2))
                    Gosub, %x2%
                Else
                {
                    Transform, x0, Deref, %x2%
                    Loop, Parse, f_, `,
                        StringReplace, x0, x0, %A_LoopField%, ¥%A_LoopField%¥, All
                    Loop, Parse, f_, `,
                        StringReplace, x0, x0, ¥%A_LoopField%¥, {%A_LoopField%}, All
                    Loop, Parse, f, `,
                        StringReplace, x0, x0, %A_LoopField%, {%A_LoopField%}, All
                    SendInput, %x0%
                }
            }
        }
        If (StrLen(s) > w)
            StringTrimLeft, s, s, w // 2
    }
    Else ; assert
    {
        StringReplace, k, k, `n, \n, All ; normalize
        StringReplace, k, k, `r, \r, All
        Loop, Parse, t, `n
        {
            l = %A_LoopField%
            If (SubStr(l, 1, InStr(l, "`r") - 1) == k)
                StringReplace, t, t, `n%l%
        }
        If a !=
            t = %t%`n%k%`r%a%`r%Options%
    }
    Return
    __hs: ; event
    hotstrings("", "", Options)
    Return
}

4 个答案:

答案 0 :(得分:0)

您可以尝试通过摆弄SetBatchLines来加快hotkeys功能:

hotstrings(k, a = "", Options:="")
{
    prevBatchlines := A_BatchLines
    SetBatchLines, -1


    ... ; rest of function here


    }

    ; reset to whatever it was 
    SetBatchLines, %prevBatchlines%

    Return

    __hs: ; event
        hotstrings("", "", Options)
    Return
}

虽然通常不推荐(由于某种原因,默认情况下它非零),但有时这是唯一的方法。

答案 1 :(得分:0)

也许试一试,设置等待你的所需的语法:

code:=
for k, v in StrSplit("QWERTYUIOPASDFGHJKLZXCVBNM")
    Hotkey, % "~" v, WaitForBarcode 
Loop 10 {
    Hotkey, % "~" (10-A_Index) "", WaitForBarcode 
    Hotkey, % "~Numpad" (10-A_Index) "", WaitForBarcode  
}
return

FoundCode(var) {
    MsgBox % "Caught code: " var
}

WaitForBarcode(){
    global code
    k:=SubStr(A_ThisHotkey,0)
    code.=k
    code:=(is(SubStr(code,1,2))=1)?k:(is(SubStr(code,3,4))=2)?k:(is(SubStr(code,7,5))=1)?k:(StrLen(code)=11)?FoundCode(code):code
}

is(var) {
    if var is not digit
        return 1
    if var is not alpha
        return 2
}

我无法使用键盘以外的任何输入设备进行测试,也许它可以正常工作,也许不会。

循环键的替代方法是:

Loop 43
  Hotkey, % "~" Chr(A_Index+47), Bar 

答案 2 :(得分:0)

在工作中,我们有许多USB条形码扫描仪,可以将扫描结果输入键盘缓冲区。

如果您可以使用条形码扫描仪并且它是硬件扫描仪, 您通常可以定义扫描程序在扫描之前必须发送的前缀/后缀代码。检查您的扫描仪手册,通常只需扫描几个条形码就可以设置它。

如果您将前缀代码定义为热键,则可以运行代码来捕获字母,直到修复后。

关键捕获的一个简单示例是

Loop {
    Input, key, I L1 V
    log = %log%%key%
}

#s::MsgBox, 64, Key History, %log%

应该很容易将其更改为在您选择的后缀键后停止循环。

来源here

答案 3 :(得分:0)

虽然它不是解决方案,但我设法找到了一种解决方法,方法是将扫描仪的后缀从回车符更改为制表符并使用我发布的原始方法。