私のガールフレンドが時間通りに家に帰ることを許した決定について、あなたはカットの下で読むことができます。
さらに、彼らがしたことのかなりの部分を自動化することができます:フロントからのデータの受信、Excelドキュメントへの記入、フロントでのデータの更新など。
この状況で実行できる最も合理的なことは、必要な機能の開発に関する作業指示書を作成し、それを当局を通じて開発者に渡すことです。 ただし、この削減は開発者を含む全員に影響を及ぼしました。 その結果、この自動化を実装するのに十分なリソースがありませんでした。 また、同社は、近い将来、特殊なRPAシステムを購入する予定もありませんでした。
さらに、従業員が仕事で何をしていて、どのアプリケーションで働いているかについての監視を強化しました。
これらすべての不利な状況の結果と私が必死に助けたいという願望に基づいて、私はVBAでExcelの関数を書くことにしました。
製品の要件
出発点として、私は感情に応じて少女がほとんどの時間を費やしたタスクを選択しました。 このタスクの一環として、少女は以下を必要としました。
- 記事番号をExcelファイルからフロントオフィスシステムの検索バーに転送します。
- この記事では、検索結果から購入、販売価格、いくつかの付加価値を取得します。
- 収集されたデータをExcelで処理して、最終製品の価格を作成します。
- システムに価格をアップロードし直します。
- 1日あたりのアンロードとそれに続くデータのロードには約3時間かかりました。
私のガールフレンドにはプログラミングの知識がなかったため、Excelの関数の形式でシンプルで使い慣れたインターフェイスを備えたツールを作成する必要がありました。 アクションのシーケンスは、単に関数のシーケンスとして定義する必要があります。 一言で言えば、 KISS 。
このケースに基づいて、次の機能要件を作成しました。
- マウス(移動、キーストローク)を制御して、画面上の対応する要素を強調表示します。
- キーボードのキーストロークをシミュレートしてデータを入力します。
- Excelからサードパーティアプリケーションにデータを転送します。
- Excelのアプリケーションからデータを取得します。
- Excelで数式をプルするときに同じタイプの操作を実行します。
マウスと最初の困難
カーソルをどこかに移動する前に、カーソルをどこに移動するかを正確に理解する必要があります。 この状況では、カーソルが特定の要素の上にあるときの位置を単純に記憶することが最も適切であるように思えます。 座標を記憶するために、user32ライブラリのGetCursorPos関数を使用しました。
さて、座標を取得しました。今では覚えておくといいでしょう。 アクティブなセルから1つまたは2つのセルを数え、X座標とY座標を書き留めるだけで複雑だとは思いませんでしたが、ActiveCell.Offset(0、1).Value = xは機能しませんでした。 値は変更されていません。 そして、実行の結果として、エラー。 さまざまな仮定を確認した結果、シートの値を変更するとシート全体の再集計が行われ、そのため、この再集計の原因となる式が判明しました。 この制限を回避するために、これらの呼び出しを特定のアクションの関数からの直接呼び出しの代わりにEvaluateに置き換える必要がありました。これにより、目的の結果を得ることができました。
結果はPrintCursorPosition()関数であり、関数の実行時のカーソル位置を右側の2つのセルに記録しました。 数式を入力する領域にPrintCursorPosition()と入力し、カーソルを移動して、キーボードのEnterキーを押す必要がありました。
マウスを移動するには、同じuser32ライブラリのSetCursorPosを使用しました。 この関数を使用するには、以前に入力として保存されていたx座標とy座標の値を渡す必要がありました。 SetCursorPosition(x、y)を使用して、以前に保存された座標上でカーソルを移動できました。 最初の目に見える結果。 やった!
マウスアクションをシミュレートするために、同じuser32ライブラリのmouse_eventを使用しました。 キーのフラグを入力に渡すことで、対応するキーのキーストロークをシミュレートできました。 当初、私は1つの関数MouseButtonPrees(フラグ)を書くことを計画していました。ここで、フラグは押されたキーのシンボルです。 このアプローチにより、結果の関数を読みやすくなります。
キーボード
VBAには、必要なすべてのアクションを実行するSendKeysステートメントがあります。 テキストは、セルへの参照によって関数に簡単に渡され、問題なく実行されます。 ただし、特殊キー(Enter、Tab、Alt、Ctrl、キーボードの矢印など)を押すと拒否されました(押すには、中括弧{ENTER}で記述する必要がありました)。 したがって、最も頻繁に使用されるものについては、PressEnter()のような関数を作成しました。 めったに使用されないため、同じドキュメントにチートシートを作成しました。
バッファにコピーしてバッファから貼り付けることにより、システムとExcelの間で情報が転送されました。 バッファーへのコピーは、基本的にControl + Cを押すことをシミュレートすることで実行され、その後、バッファーからのデータがMSForms.DataObjectに取り込まれ、特定のセルに転送されました。
テストとパフォーマンスの問題
問題はすぐに始まりました。
一連のアクションのスクリプトを記述するプロセスは、アクションの小さなグループを作成し、それらを1つに結合することで構成されます。 しかし、フリーセルに切り替えると、シーケンス全体がすぐに解決されました。これは、特にアクションのグループが10秒以上かかる場合に非常に迷惑でした。 この問題を解決するために、関数名のアクティブセルの数式テキストに存在するかどうかを確認しました。 助けた。
さらに、テスト中に、何が機能し何が機能しなかったかを追跡するために、待機関数WaitS(秒)とWaitMS(ミリ秒)を追加しました。 kernel32ライブラリのSleepに基づいています。 WaitSとWaitMSの違いは、WaitMSではミリ秒単位で、WaitSでは秒単位であるということです。
もう1つの問題は、セルに引き込まれたときの関数の一貫性のない実行でした。 これは、Excelの非同期計算によるものです。 彼は各セルの計算を異なるプロセッサに配布しました。 その結果、シーケンスは最初にセル2で実行され、次に5番目に実行され、次に3番目に実行されます。 さらに、シーケンス自体は最初から最後まで問題なく実行されました。 この動作をなくすために、Excelの設定(Excelの設定->詳細->数式)でマルチスレッド計算をオフにしました。
結果
これらすべての操作方法を説明し、使用方法を学習した後、彼はガールフレンドにこのような恩知らずな方法で会社のプロセスを自動化させました。
このような自動化のおかげで、時間が3時間から30分に短縮されました。 同時に、自動化により、データのアップロードおよびダウンロードのプロセスに対するアプローチをわずかに変更することができました。 荷降ろしは、私のガールフレンドが昼食に出て夜に荷を積むときに発生します。 このように、作業日数のほぼ半分で負荷が減少したと言えます。これにより、ガールフレンドは時間通りに帰宅でき、自動化よりも面白いことができます。