RPA初心者による無料でRPA

RPAやIOTに関するブログ …時々富士山

6.SAP CO01

CO01製造指図登録について、自動化手法を説明します。

エクセルに登録したい品目コード、製造予定数量、製造日、追加したい原料を入力します。
エクセル例
f:id:hero32:20200311080542j:plain

黄色列に入力してもらい、青列(F列)に登録した指図番号が記載されていきます。
A列:品目名と品目コード(人が読みやすいようにしています)
B列:製造予定日(人が読みやすいように月/日としています)
D列:製造予定数量

尚、緑列(O、P 列)はコンピュータに読み取らせるために、品目名とコードをコードのみにしたり(O列)、日付を2020/03/12のように変更しています(P列)。

f:id:hero32:20200311080554j:plain

こちらは、VLOOKUPのための情報と、追加品目です。
基本的に、製造は予定数量や追加品目がいつも同じくなので、品目名と品目コードを入れると、VLOOKUPで自動入力にしています。
追加品目については、W~Z列に入力します。
W列:追加品目がある場合○を入力
X,Y,Z列:追加品目のコードを入れます。

緑列(AB~AE列)はA列の値を元に追加がある場合、品目コードを表示します。

例)AB,3セルの中身
追加品目がある場合、X列の値となるようにしています。
=IF(IFERROR(VLOOKUP($A3,$S$3:$Z$70,5,FALSE),"")="","",IFERROR(VLOOKUP($A3,$S$3:$Z$70,5,FALSE),""))

これでエクセル完了です


以下コード表示
コードについては、今後もっと分かりやすく説明文を入れます。

Add-Type -AssemblyName Microsoft.VisualBasic
Add-Type -AssemblyName System.Windows.Forms

#処理に入る前にSAPID、SAPPASSを定義(■PASSが変ったらここで変更する■)
$SAPID = "★1"
$SAPPASS = "★2"

# 検索先フォルダー
$fpath  = “★3”

# Applicationオブジェクト作成
$xls = New-Object -ComObject Excel.Application

# Excel 非表示
$xls.visible = $false
# Excel ファイル名取得
$FullName = get-childitem $fpath -include *.xls,*.xlsx
#ブックオープン
$book = $xls.Workbooks.Open($FullName)
#シート1を選択
$sheet = $book.Worksheets.item("1")
$end = $sheet.cells.Item(1,15).Value()
echo $end
#各種の配列を宣言
$code_array = @{}
$ryo_array = @{}
$bi_array = @{}
$gyo_array = @()
$tuika_hantei_array = @{}
$tsuika_array1 = @{}
$tsuika_array2 = @{}
$tsuika_array3 = @{}

#繰り返しスタート
for ($i = 3; $i -lt $end; $i++)
{
#品目コード取得、配列投入
$code = $sheet.cells.Item($i,15).Value()
$hannei =  $sheet.cells.Item($i,6).Value()
    if ([string]::IsNullOrEmpty($code))
    {
    }
    else
    {
        #すでに読み込まれていたら、読み込まない
        if ([string]::IsNullOrEmpty($hannei))
        {
        $code_array.Add("$i",$code)
        #予定数量取得
        $ryo = $sheet.cells.Item($i,4).Value()
        $ryo_array.Add("$i",$ryo)
        #製造日取得
        $bi = $sheet.cells.Item($i,16).Value()
        $bi_array.Add("$i",$bi)
        $gyo_array += $i

            #追加があるか判定用に取得
            $tuika_hantei = $sheet.cells.Item($i,28).Value()
            echo $tuika_hantei
            if([string]::IsNullOrEmpty($tuika_hantei))
            {
            }
            else
            {
            $tuika_hantei_array.Add("$i",$tuika_hantei)
            }
            #追加1を取得
            $tsuika1 = $sheet.cells.Item($i,29).Value()
            echo $tsuika1
            if([string]::IsNullOrEmpty($tsuika1))
            {
            }
            else
            {
            $tsuika_array1.Add("$i",$tsuika1)
            }
            #追加2を取得
            $tsuika2 = $sheet.cells.Item($i,30).Value()
            echo $tsuika2
            if([string]::IsNullOrEmpty($tsuika2))
            {
            }
            else
            {
            $tsuika_array2.Add("$i",$tsuika2)
            }
            #追加3を取得
            $tsuika3 = $sheet.cells.Item($i,31).Value()
            echo $tsuika3
            if([string]::IsNullOrEmpty($tsuika3))
            {
            }
            else
            {
            $tsuika_array3.Add("$i",$tsuika3)
            }
        }
        else
        {
        }
    }
}

#すべて「空欄」だったら、終了
$gyocount = $gyo_array.Count

if ($gyocount -eq "0")
{
$book.Save();
$book.Close();
$xls.Quit()
Remove-Variable xls
[GC]::Collect()
#エラーメッセージ
[System.Windows.Forms.MessageBox]::Show("すでに指図番号が入っています")
EXIT
}
else
{}

#-Begin-----------------------------------------------------------------

$Sig = @'
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
'@

  #-Add FindWindow function---------------------------------------------
    $Win32 = Add-Type -Namespace Win32 -Name Funcs -MemberDefinition $Sig -PassThru

  #-Set the path to the SAP GUI directory-------------------------------
    $SAPGUIPath = "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\"

  #-Set the SAP system ID or the IP address-----------------------------
    $SID = "★4"

  #-Set the instance number of the SAP system---------------------------
    $InstanceNo = "00"

  #-Starts the SAP GUI--------------------------------------------------
    $SAPGUI = $SAPGUIPath + "sapgui.exe"
    & $SAPGUI $SID $InstanceNo

  While ($Win32::FindWindow("SAP_FRONTEND_SESSION", "SAP") -eq 0) {
    Start-Sleep -Milliseconds 250
  }

#-Begin-----------------------------------------------------------------

  #-Get-Property--------------------------------------------------------
    function Get-Property {
      param([__ComObject] $object, [String] $propertyName)
      $objectType = [System.Type]::GetType($object)
      $objectType.InvokeMember($propertyName,
        "GetProperty", $NULL, $object, $NULL)
    }

  #-Set-Property--------------------------------------------------------
    function Set-Property {
      param([__ComObject] $object, [String] $propertyName,
        $propertyValue)
      $objectType = [System.Type]::GetType($object)
      [Void] $objectType.InvokeMember($propertyName,
        "SetProperty", $NULL, $object, $propertyValue)
    }

  #-Invoke-Method-------------------------------------------------------
    function Invoke-Method {
      param([__ComObject] $object, [String] $methodName,
        $methodParameters)
      $objectType = [System.Type]::GetType($object)
      $output = $objectType.InvokeMember($methodName,
        "InvokeMethod", $NULL, $object, $methodParameters)
      if ( $output ) { $output }
    }

  #-Main----------------------------------------------------------------
    $SapGuiAuto = [microsoft.visualbasic.Interaction]::GetObject("SAPGUI")
    $application = Invoke-Method $SapGuiAuto "GetScriptingEngine"
    $connection = Get-Property $application "Children" @(0)
    $session = Get-Property $connection "Children" @(0)

    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-MANDT")
    Set-Property $ID "Text" @("010")
    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-BNAME")
    Set-Property $ID "Text" @("$SAPID")
    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/pwdRSYST-BCODE")
    Set-Property $ID "Text" @("$SAPPASS")
    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-LANGU")
    Set-Property $ID "Text" @("JA")
    $ID = Invoke-Method $session "findById" @("wnd[0]")
    Invoke-Method $ID "sendVKey" @(0)

    $ID = Invoke-Method $session "findById" @("wnd[0]")
    Invoke-Method $ID "sendVKey" @(29) 
    $ID = Invoke-Method $session "findById" @("wnd[1]/usr/txt130_FIND")
    Set-Property $ID "text" @("CO01") 
    $ID = Invoke-Method $session "findById" @("wnd[1]")
    Invoke-Method $ID "sendVKey" @(0)
    $ID = Invoke-Method $session "findById" @("wnd[0]")
    Invoke-Method $ID "sendVKey" @(8) 

    #数値代入
    $j = $gyo_array[0]
    echo $j
    $k_code = $code_array["$j"]
    $k_ryo =  $ryo_array["$j"]
    $k_bi = $bi_array["$j"]

    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/ctxtCAUFVD-MATNR")
    Set-Property $ID "text" @("$k_code")   
    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/ctxtCAUFVD-WERKS")
    Set-Property $ID "text" @("★5")       
    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/ctxtAUFPAR-PP_AUFART")
    Set-Property $ID "text" @("Z001")

    $ID = Invoke-Method $session "findById" @("wnd[0]")
    Invoke-Method $ID "sendVKey" @(0)
    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tabsTABSTRIP_0115/tabpKOZE/ssubSUBSCR_0115:SAPLCOKO1:0120/txtCAUFVD-GAMNG")
    Set-Property $ID "text" @("$k_ryo")     
    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tabsTABSTRIP_0115/tabpKOZE/ssubSUBSCR_0115:SAPLCOKO1:0120/ctxtCAUFVD-GSTRP")
    Set-Property $ID "text" @("$k_bi")
    $ID = Invoke-Method $session "findById" @("wnd[0]")
    Invoke-Method $ID "sendVKey" @(0)


        #原料を追加
        #追加する原料があるか確認して条件分岐
        $k_tuika_hantei = $tuika_hantei_array["$j"]
        if($k_tuika_hantei -eq "○")
        {
        #追加1の登録
        $k_tsuika1 = $tsuika_array1["$j"]

        $ID = Invoke-Method $session "findById" @("wnd[0]/tbar[1]/btn[6]")
        Invoke-Method $ID "press"
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-MATNR[1,26]")
        Set-Property $ID "text" @("$k_tsuika1")
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRESBD-MENGE[3,26]")
        Set-Property $ID "text" @("0.001")
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-EINHEIT[4,26]")
        Set-Property $ID "text" @("kg")
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-POSTP[5,26]")
        Set-Property $ID "text" @("L")
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRESBD-VORNR[6,26]")
        Set-Property $ID "text" @("0010")
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRCOLS-APLFL[7,26]")
        Set-Property $ID "text" @("0")
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-WERKS[8,26]")
        Set-Property $ID "text" @("★5")
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-LGORT[9,26]")
        Set-Property $ID "text" @("★6")
        $ID = Invoke-Method $session "findById" @("wnd[0]")
        Invoke-Method $ID "sendVKey" @(0)

            #追加2
            $k_tsuika2 = $tsuika_array2["$j"]
            if([string]::IsNullOrEmpty($k_tsuika2))
            {
            }
            else
            {
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-MATNR[1,27]")
            Set-Property $ID "text" @("$k_tsuika2")
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRESBD-MENGE[3,27]")
            Set-Property $ID "text" @("0.001")
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-EINHEIT[4,27]")
            Set-Property $ID "text" @("kg")
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-POSTP[5,27]")
            Set-Property $ID "text" @("L")
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRESBD-VORNR[6,27]")
            Set-Property $ID "text" @("0010")
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRCOLS-APLFL[7,27]")
            Set-Property $ID "text" @("0")
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-WERKS[8,27]")
            Set-Property $ID "text" @("★5")
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-LGORT[9,27]")
            Set-Property $ID "text" @("★6")
            $ID = Invoke-Method $session "findById" @("wnd[0]")
            Invoke-Method $ID "sendVKey" @(0)

               #追加3
                $k_tsuika3 = $tsuika_array3["$j"]           
                if([string]::IsNullOrEmpty($k_tsuika3))
                {
                }
                else
                {
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-MATNR[1,28]")
                Set-Property $ID "text" @("$k_tsuika3")
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRESBD-MENGE[3,28]")
                Set-Property $ID "text" @("0.001")
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-EINHEIT[4,28]")
                Set-Property $ID "text" @("kg")
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-POSTP[5,28]")
                Set-Property $ID "text" @("L")
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRESBD-VORNR[6,28]")
                Set-Property $ID "text" @("0010")
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRCOLS-APLFL[7,28]")
                Set-Property $ID "text" @("0")
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-WERKS[8,28]")
                Set-Property $ID "text" @("★5")
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-LGORT[9,28]")
                Set-Property $ID "text" @("★6")
                $ID = Invoke-Method $session "findById" @("wnd[0]")
                Invoke-Method $ID "sendVKey" @(0)
                }
            }
        }
        else
        {
        echo "追加なし"
        }

    #登録
    $ID = Invoke-Method $session "findById" @("wnd[0]/tbar[0]/btn[11]")
    Invoke-Method $ID "press"

    #CO01参照を開く
    $ID = Invoke-Method $session "findById" @("wnd[0]/mbar/menu[0]/menu[5]")
    Invoke-Method $ID "select" 
    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/ctxtCAUFVD-AUFNR")
    $GET = Get-Property $ID "text"

    #CO01参照を閉じる
    $ID = Invoke-Method $session "findById" @("wnd[0]/mbar/menu[0]/menu[10]")
    Invoke-Method $ID "select"

    #エクセルに貼り付け
    $GET_array = @()
    $GET_array += $GET

    echo $code_array["$j"]
    echo $ryo_array["$j"]
    echo $bi_array["$j"]
    echo $GET

    #コピーが指図番号ではない場合、終了
    if($GET_array[0].Length -ne "12")
    {
    #エクセル終了
    $book.Save();
    $book.Close();
    $xls.Quit()
    Remove-Variable xls
    [GC]::Collect()

    #エラーメッセージ
    [System.Windows.Forms.MessageBox]::Show("指図番号をコピーできませんでした…1")
    EXIT
    }
    else
    {
    }

    $sheet.cells.Item($j,6) = $GET_array[0]

    #繰り返し
    $endg = $gyo_array.Count

        for ($g = 1; $g -lt $endg; $g++)
        {
        $j = $gyo_array[$g]
        echo $j

        $k_code = $code_array["$j"]
        $k_ryo =  $ryo_array["$j"]
        $k_bi = $bi_array["$j"]

        $ID = Invoke-Method $session "findById" @("wnd[0]")
        Invoke-Method $ID "sendVKey" @(29) 
        $ID = Invoke-Method $session "findById" @("wnd[1]/usr/txt130_FIND")
        Set-Property $ID "text" @("CO01") 
        $ID = Invoke-Method $session "findById" @("wnd[1]")
        Invoke-Method $ID "sendVKey" @(0)
        $ID = Invoke-Method $session "findById" @("wnd[0]")
        Invoke-Method $ID "sendVKey" @(8)

        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/ctxtCAUFVD-MATNR")
        Set-Property $ID "text" @("$k_code")   
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/ctxtCAUFVD-WERKS")
        Set-Property $ID "text" @("★5")       
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/ctxtAUFPAR-PP_AUFART")
        Set-Property $ID "text" @("Z001") 
        $ID = Invoke-Method $session "findById" @("wnd[0]")
        Invoke-Method $ID "sendVKey" @(0)

        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tabsTABSTRIP_0115/tabpKOZE/ssubSUBSCR_0115:SAPLCOKO1:0120/txtCAUFVD-GAMNG")
        Set-Property $ID "text" @("$k_ryo")     
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tabsTABSTRIP_0115/tabpKOZE/ssubSUBSCR_0115:SAPLCOKO1:0120/ctxtCAUFVD-GSTRP")
        Set-Property $ID "text" @("$k_bi")     
        $ID = Invoke-Method $session "findById" @("wnd[0]")
        Invoke-Method $ID "sendVKey" @(0)

        #原料を追加
        #追加する原料があるか確認して条件分岐
        $k_tuika_hantei = $tuika_hantei_array["$j"]
        if($k_tuika_hantei -eq "○")
        {
        #追加1の登録
        $k_tsuika1 = $tsuika_array1["$j"]

        $ID = Invoke-Method $session "findById" @("wnd[0]/tbar[1]/btn[6]")
        Invoke-Method $ID "press"
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-MATNR[1,13]")
        Set-Property $ID "text" @("$k_tsuika1")
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRESBD-MENGE[3,13]")
        Set-Property $ID "text" @("0.001")
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-EINHEIT[4,13]")
        Set-Property $ID "text" @("kg")
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-POSTP[5,13]")
        Set-Property $ID "text" @("L")
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRESBD-VORNR[6,13]")
        Set-Property $ID "text" @("0010")
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRCOLS-APLFL[7,13]")
        Set-Property $ID "text" @("0")
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-WERKS[8,13]")
        Set-Property $ID "text" @("★5")
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-LGORT[9,13]")
        Set-Property $ID "text" @("★6")
        $ID = Invoke-Method $session "findById" @("wnd[0]")
        Invoke-Method $ID "sendVKey" @(0)

            #追加2
            $k_tsuika2 = $tsuika_array2["$j"]
            if([string]::IsNullOrEmpty($k_tsuika2))
            {
            }
            else
            {
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-MATNR[1,14]")
            Set-Property $ID "text" @("$k_tsuika2")
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRESBD-MENGE[3,14]")
            Set-Property $ID "text" @("0.001")
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-EINHEIT[4,14]")
            Set-Property $ID "text" @("kg")
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-POSTP[5,14]")
            Set-Property $ID "text" @("L")
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRESBD-VORNR[6,14]")
            Set-Property $ID "text" @("0010")
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRCOLS-APLFL[7,14]")
            Set-Property $ID "text" @("0")
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-WERKS[8,14]")
            Set-Property $ID "text" @("★5")
            $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-LGORT[9,14]")
            Set-Property $ID "text" @("★6")
            $ID = Invoke-Method $session "findById" @("wnd[0]")
            Invoke-Method $ID "sendVKey" @(0)

                #追加3
                $k_tsuika3 = $tsuika_array3["$j"]           
                if([string]::IsNullOrEmpty($k_tsuika3))
                {
                }
                else
                {
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-MATNR[1,15]")
                Set-Property $ID "text" @("$k_tsuika3")
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRESBD-MENGE[3,15]")
                Set-Property $ID "text" @("0.001")
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-EINHEIT[4,15]")
                Set-Property $ID "text" @("kg")
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-POSTP[5,15]")
                Set-Property $ID "text" @("L")
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRESBD-VORNR[6,15]")
                Set-Property $ID "text" @("0010")
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/txtRCOLS-APLFL[7,15]")
                Set-Property $ID "text" @("0")
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-WERKS[8,15]")
                Set-Property $ID "text" @("★5")
                $ID = Invoke-Method $session "findById" @("wnd[0]/usr/tblSAPLCOMKTCTRL_0120/ctxtRESBD-LGORT[9,15]")
                Set-Property $ID "text" @("★6")
                $ID = Invoke-Method $session "findById" @("wnd[0]")
                Invoke-Method $ID "sendVKey" @(0)
                }
            }
        }
        else
        {
        echo "追加なし"
        }

        $ID = Invoke-Method $session "findById" @("wnd[0]/tbar[0]/btn[11]")
        Invoke-Method $ID "press"
        $ID = Invoke-Method $session "findById" @("wnd[0]/mbar/menu[0]/menu[5]")
        Invoke-Method $ID "select" 
        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/ctxtCAUFVD-AUFNR")
        $GET = Get-Property $ID "text"

        #CO01参照を閉じる
        $ID = Invoke-Method $session "findById" @("wnd[0]/mbar/menu[0]/menu[10]")
        Invoke-Method $ID "select"

        #
        $GET_array += $GET
        $gr = $g-1

        echo $code_array["$j"]
        echo $ryo_array["$j"]
        echo $bi_array["$j"]
        echo $GET

            #コピーが指図番号ではない場合、終了
            if(($GET_array[$g].Length -ne "12") -Or ($GET_array[$g] -eq $GET_array[$gr]))
            {
            #エクセル終了
            $book.Save();
            $book.Close();
            $xls.Quit()
            Remove-Variable xls
            [GC]::Collect()
            #エラーメッセージ
            [System.Windows.Forms.MessageBox]::Show("指図番号をコピーできませんでした…2")
            EXIT       
            }
            else
            {
            $sheet.cells.Item($j,6) = $GET_array[$g]
            }
        }

    #SAPを閉じる
    $ID = Invoke-Method $session "findById" @("wnd[0]")
    Invoke-Method $ID "close"   
    $ID = Invoke-Method $session "findById" @("wnd[1]/usr/btnSPOP-OPTION1")
    Invoke-Method $ID "press"     

    $book.Save();
    $book.Close();
    $xls.Quit()
    Remove-Variable xls
    [GC]::Collect()

    #一応終わりましたと表示
    [System.Windows.Forms.MessageBox]::Show("たぶん、成功しました!")

#-End--------------------------------

★1:SAPのログインID
★2:SAPのログインPASS
★3:エクセルの場所(フォルダパス)
※処理したいエクセル以外は何も入れないで下さい
★4:SAPのログインサーバ(4.SAPシステムを動かす参照)
★5:プラント名(各社で異なります)
★6:スロック名(各社で異なります)

【Tips】powershell コマンド調べ方

powershellの参考書が少なく、何を使っていいか分からないことが多いです。
基本的にコマンドは、動詞+名詞で表現されているため、推定しやすいです(動詞:get,set,write、名詞:process,item等)。
また、powershellには使えそうなコマンドをリストアップしてくれたり、使い方を教えてくれる対話機能があります。
これらを駆使して、調べていきます。

●コマンドの検索

#Processという名前をもつコマンドをすべて検索
Get-Command *Process*

結果
f:id:hero32:20200310111138j:plain


●コマンドの使い方
上記の結果の中で、Get-Processの使い方を調べる

Get-help Get-Process -Online

結果(ieが立ち上がる)
f:id:hero32:20200310111224j:plain

例が出てくるので、分かりやすいです。


この機能のせいで、参考書が少ないかな…

【Tips】プリンタ変更

プリンタ変更方法

$Printers=Get-WmiObject Win32_Printer
    $Printer=$Printers | Where-Object Name -eq "Canon"
    $Printer.SetDefaultPrinter()

Canon部分をご自身が使用するプリンタ名に変更してください。

これを利用して、SAPで印刷される前によく使うプリンタを変更し、印刷。
その後、上記のスクリプトをいつも使うプリンタ名にしたスクリプトを実行し、プリンタを元に戻します。

なぜこのようにしているかというと、SAP印刷では『社外秘』が印刷されないため、プリンタドライバのスタンプ機能を使用して、『社外秘』を付けて印刷しています。
今までは『社外秘』を本当のスタンプで押していましたがようやくデジタル化

3.フォルダ内比較

今回はフォルダ内の比較方法、バックアップ方法を説明します。
私はこれを利用してSDSの管理を行っています。
私の部署では、営業や、企画、研究、製造、物流等の各箇所が入手したSDSを共通ネットワーク上のフォルダにそれぞれ収納し管理しています。これにより誰でも最新版を閲覧できます。一方、製造現場では紙によるファイルを保管しております(この理由としては、pcの数が少ない現場や、紙の方がアクセスしやすい点が挙げられます。古い体質だけどね…)。これより、常に最新版を印刷して保管しておく必要があります。紙ファイルが最新版でないと、社内パトロールで指摘されることになります。
各箇所が共通ネットワークフォルダにSDSを入れた時に、連絡してくれればいいのですが、なかなか難しいです。

そこで、powershellと、同じくwindows標準のタスクスケジューラを使用して、週1回フォルダ内に更新があったか確認するプログラムを作成しました。

●長くなりましたが、以下がプログラムです。

#SDSフォルダの更新確認
#■検索フォルダ
$New_path = 'C:\Users\Desktop\1'
#■比較フォルダ
$Old_path =  'C:\Users\Desktop\2'

#検索フォルダ情報取得
$New1 = get-childitem -path $New_path -recurse
#比較フォルダ情報取得
$Old1 = get-childitem -path $Old_path -recurse
#比較
$compare = compare-object $New1 $Old1
#更新されてたら、テキストファイルを作成
if ([string]::IsNullOrEmpty($compare))
    {
    }
    else
    {
    $Today = (Get-Date).AddDays(0).ToString("yyyyMMdd")
    $textfilename = "★SDS更新あり_" + "$Today" + ".txt"
 #■テキスト出力
    compare-object $New1 $Old1 | Out-File C:\Users\Desktop\$textfilename

    #Oldフォルダを現在に更新
    robocopy $New_path $Old_path /MIR /XO /NP
    }

プログラム内の■を自分のフォルダパスに置き換えて下さい。
○フォルダの住所を表すフォルダパスの確認方法
フォルダを開いて、赤枠で確認できます。
f:id:hero32:20200220081534j:plain

●解説
共通ネットワークフォルダと自分のpcのフォルダを比較し、更新されたファイルのみをコピーし、その結果をテキストファイルで出力します。


また、タスクスケジューラの登録方法は以下です。

f:id:hero32:20200309183549j:plain

私は毎週水曜日の休み時間中に起動させています。指定時間になるとpowershellウインドウが突然起動します。

●バックアップ
下記コードでは、更新された分だけフォルダ内をバックアップします。

#■検索フォルダ
$New_path = 'C:\Users\Desktop\1'
#■比較フォルダ
$Old_path =  'C:\Users\Desktop\2'

robocopy $New_path $Old_path /MIR /XO /NP

私の会社では共通ネットワークフォルダを全社的にバックアップするシステムを持っていますが、間違って消してしまったファイルを復元してもらうには、申請書の起案が必要で時間がかかります。
このため、課の共通ネットワークフォルダを外付けHDDにバックアップし、課内で対応しています。
バックアップはたくさんある方がいいしね。

5.SAPシステムを動かす2

SAP関連コードの作り方

4章で説明したように座標、アクション(テキスト入力、読み取りやチェックボックスのチェック等)の調べ方を説明します。

実はSAPにはエクセルマクロ記録のように行った操作を記録してくれる機能が付いています!この機能が付いているということは、SAP自体も自動化を推奨していると言えます。

●SAP自動化の手順↓

1

23
f:id:hero32:20200225074824j:plain
45
f:id:hero32:20200225074906j:plain
67
f:id:hero32:20200225075624j:plain
89
f:id:hero32:20200225074950j:plain

エクセルで変換ファイルを作成しましたが、馴れてくると手動で編集する方が楽です。

VBScriptを実行する前にSAP上の設定でスクリプト利用の解除を行います
解除は以下の手順です。

オプションから
f:id:hero32:20200313073744j:plain
アクセシビリティ&スクリプトスクリプト→赤枠チェックを図のようにする
f:id:hero32:20200313073811j:plain

このVBScriptを実行すると(ダブルクリック)、先ほど行った操作がものすごい速度で再現されます。
VBScriptを編集するとエクセルや様々なソフトと連携出来ますが、現時点ではpowershellの出現、ie11ではデフォルトで無効となっていたりと、マイナーな言語になって言っております。VBScriptにはVBScriptの利点があるので無くなることは無いですが、せっかくなのでVBScriptpowershellに変換して、作成していきます。

4章で話したように、座標指定、アクションを繰り返していきます。


★テキスト入力:CO01で品目コード入力
VBScript記載

session.findById("wnd[0]/usr/ctxtCAUFVD-MATNR").text = "999999"

powershell

$ID = Invoke-Method $session "findById" @("wnd[0]/usr/ctxtCAUFVD-MATNR")
Set-Property $ID "Text" @("999999")

★テキスト読み取り
powershell

$ID = Invoke-Method $session "findById" @("wnd[0]/usr/ctxtCAUFVD-MATNR")
$GET = Get-Property $ID "text"

$GETにテキストが収納されます

★ボタンクリック:CO01で構成品目概要をクリック
VBScript記載

session.findById("wnd[0]/tbar[1]/btn[6]").press

powershell

    $ID = Invoke-Method $session "findById" @("wnd[0]/tbar[1]/btn[6]")
    Invoke-Method $ID "press"   

★ショートカットキー
VBScript記載:CO01で構成品目概要をクリックせず、ショートカットキーF6(構成品目概要)を押した場合

session.findById("wnd[0]").sendVKey 6

powershell

$ID = Invoke-Method $session "findById" @("wnd[0]")
Invoke-Method $ID "sendVKey" @(6) 

ちなみにエンターキーはsendVKey 0です。作成しているとよくでて来ます。


なるべくショートカットキーを使用した方がコンピュータ側になります。マウス操作はより人間的な操作となり、今後RPAを作成していく上でコンピュータ側に変換するのに苦労することになります。また、有名なショートカットのctl +Cのように、普段からショートカットを使っている方が業務効率が上がります。

★無視しても動く記載事項

setFocus
caretPosition

4.SAPシステムを動かす

SAPとはSAP社が作成したERPパッケージです。世界的に導入している企業がたくさんあります。
このSAPを使用して、原料購入から製造、検査、出荷まで管理しています。
また、予算作成も行われており、企業にとってはなくてはならないものです。

SAPはVBScriptと呼ばれるコンピュータ言語で動いています。

VBScriptとは?
powershellと同様にwindows標準の言語です。windowsには、コマンドプロンプト(windows3~)、VBScript(windows98~)、powershell(windows7~)の言語があります。powershellは最も新しいですが、それぞれ特徴があり兄弟みたいな感じです。兄弟なのでpowershellでもSAPを動かすことができます。

●SAPを立ち上げ、ログイン
以下のスクリプトでサーバを指定して立ち上げ、ログインできます。

以下のスクリプト

echo "-----------SAP処理開始----------------"
#-Begin-----------------------------------------------------------------
#■自分のid、pass
$SAPID = ■
$SAPPASS = ■

$Sig = @'
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
'@

  #-Add FindWindow function---------------------------------------------
    $Win32 = Add-Type -Namespace Win32 -Name Funcs -MemberDefinition $Sig -PassThru

  #-Set the path to the SAP GUI directory-------------------------------
    $SAPGUIPath = "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\"

  #-Set the SAP system ID or the IP address-----------------------------
  #★サーバを指定(下記の画像参照)
    $SID = "★"

  #-Set the instance number of the SAP system---------------------------
    $InstanceNo = "00"

  #-Starts the SAP GUI--------------------------------------------------
    $SAPGUI = $SAPGUIPath + "sapgui.exe"
    & $SAPGUI $SID $InstanceNo

  While ($Win32::FindWindow("SAP_FRONTEND_SESSION", "SAP") -eq 0) {
    Start-Sleep -Milliseconds 250
  }

#-Begin-----------------------------------------------------------------

  #-Get-Property--------------------------------------------------------
    function Get-Property {
      param([__ComObject] $object, [String] $propertyName)
      $objectType = [System.Type]::GetType($object)
      $objectType.InvokeMember($propertyName,
        "GetProperty", $NULL, $object, $NULL)
    }

  #-Set-Property--------------------------------------------------------
    function Set-Property {
      param([__ComObject] $object, [String] $propertyName,
        $propertyValue)
      $objectType = [System.Type]::GetType($object)
      [Void] $objectType.InvokeMember($propertyName,
        "SetProperty", $NULL, $object, $propertyValue)
    }

  #-Invoke-Method-------------------------------------------------------
    function Invoke-Method {
      param([__ComObject] $object, [String] $methodName,
        $methodParameters)
      $objectType = [System.Type]::GetType($object)
      $output = $objectType.InvokeMember($methodName,
        "InvokeMethod", $NULL, $object, $methodParameters)
      if ( $output ) { $output }
    }

  #-Main----------------------------------------------------------------
    $SapGuiAuto = [microsoft.visualbasic.Interaction]::GetObject("SAPGUI")
    $application = Invoke-Method $SapGuiAuto "GetScriptingEngine"
    $connection = Get-Property $application "Children" @(0)
    $session = Get-Property $connection "Children" @(0)

    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-MANDT")
    Set-Property $ID "Text" @("010")
    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-BNAME")
    Set-Property $ID "Text" @("$SAPID")
    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/pwdRSYST-BCODE")
    Set-Property $ID "Text" @("$SAPPASS")
    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-LANGU")
    Set-Property $ID "Text" @("JA")
    $ID = Invoke-Method $session "findById" @("wnd[0]")
    Invoke-Method $ID "sendVKey" @(0)

以上スクリプト

★サーバは各社で異なるため、
以下画像のメッセージサーバ(赤枠内)を参照してください。
f:id:hero32:20200218071712p:plain


SAPコードの解説

①座標指定
$ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-BNAME")
②アクション(テキスト入力)
Set-Property $ID "Text" @("$SAPID")

SAPコードは上記のように①座標指定、②テキスト入力で1セットになっており、これの繰り返しです。

①座標指定
"wnd[0]/usr/txtRSYST-BNAME"が座標になります。前後のコードは変更せず、この座標部分のみ変更して、作成していきます。尚、この座標の調べ方は5章で説明します。

f:id:hero32:20200219073758j:plain

②アクション
Set-Propertyは直訳すると、特性を決める。つまり、①で指定した座標$IDに"$SAPID"をテキスト形式でセットするとなります。

powershellで無料RPA 【目次】

私は化学系製造業に勤めており、
powershellを用いた無料のRPA事例を紹介します。


1.powershellとは?メリット、デメリット

2.powershell起動から挨拶

3.フォルダ内比較

4.SAPシステムを動かす

5.SAPシステムを動かす2

6.SAP CO01

7.SAP MIGO製造実績入力 (作成中)

8.SAP CO11N, MSC2N, QA01(作成中)

9.





にほんブログ村 IT技術ブログへ
にほんブログ村