0.完成はこちら
デスクトップ用 Power Automateを使って、WEBへの自動入力を行いました。
みなさんこんにちは。
某小売業でECシステムに関わっています。
前回はChatGPTを使ってWEBを作成しました。(前回記事)
今回はデスクトップ用 Power Automateを使って、WEBへの自動入力に試行錯誤しました。
1.あなたの作業は資産?経費?詳細教えて!!
私の会社では、出勤と退勤を管理する勤怠システムがあります。
勤怠システムでは労働時間が集計できるものの、
作業の種別まではわからないので、別途WEBの作業工数システムに入力をしています。
なぜこのような入力作業が必要かというと、資産価値がある作業は集計して会社の資産として計上するためです。人によって入力タイミングは様々ですが、毎日終了時に入力する方や月末に入力する方がおられます。
2.コピー&ペーストで入力できない
作業工数システムのWEB入力ではコピー&ペーストができず、1作業ずつ作業ラベルを選んで、開始・終了時間を入れております。下記の画面ではなく、ラベルを選んで時間を引き延ばして変更するようなやり方もありますが、1作業ずつというのは変わらないです。
1人毎月30分くらいは、このWEBから入力に充てられています。社員20人だと10時間、年間で120時間です。また、勤怠システムの総労働時間と総入力作業時間が合わないこともあり、合わない方は月末にその修正も行ったりしています。
3.Aさんの願望 "WEBへ入力は省きたいな"
普段の業務について、効率化をAさんとお話しした際の内容になります。
Aさん:作業を空想で入力はできないにしても
せめてエクセルに記入して、ファイルのアップロードだと、楽になるよね。
コピー&ペーストもエクセルなら簡単だし。
私:ファイルのアップロードは解放もされてなくできないですよね。
では、エクセルに記入してもらい、WEBへの入力を自動化します!!
Aさん:それだと助かる!!
4.使用したツール
・PowerAutemateDesktop
・Timekrei
作業工数システムとして会社では作業の入力と集計で主に使用しております。
・Excel
5.開発
5-1.コンセプト”動けばなんでもあり”
開発時間の短縮を優先し、処理の完璧さは無視しました。
開発する中でエラーもありました。開発にはあまり時間をかけないようにしたいので、完璧な処理フローにはこだわらず、処理が繋がればOKとして進めました。そのため、本来ではありえない処理(ケース文)やクリック処理が入っております。
5-2.エクセル記入
処理するエクセルは以下のようになっております。
B列が作業日、
CとD列が作業のタスクラベル、
E列が作業時間になります。関数を使って、F列~I列へは自動で変換されます。
5-3.PowerAutemateDesktop
エクセルから情報を読み取り、Timekreiを操作しながら1行ずつ処理する流れになります。
①エクセルA列からK列を読み取り、
②Timekreiへアクセス・ログインし、
③実績のページに遷移し、
④日付で指定した詳細ページに遷移し、
⑤時間、PJコード、詳細を選択し、
⑥詳細登録し、
⑦作業の確定登録し、
⑧次の行の登録処理に移る(ループで④に戻る)
コード
# エクセル処理開始
Excel.LaunchExcel.LaunchAndOpenUnderExistingProcess Path: $'''C:\\Users\\K\\Desktop\\工数.xlsx''' Visible: True ReadOnly: False I業務tance=> ExcelI業務tance
Excel.ReadFromExcel.ReadCells I業務tance: ExcelI業務tance StartColumn: 1 StartRow: 2 EndColumn: 11 EndRow: 400 ReadAsText: False FirstLineIsHeader: False RangeValue=> ExcelData
SET NewVar2 TO ExcelData
DISABLE Display.ShowMessageDialog.ShowMessage Title: $'''r''' Message: NewVar2[行目][3] Icon: Display.Icon.None Butto業務: Display.Butto業務.OK DefaultButton: Display.DefaultButton.Button1 IsTopMost: False ButtonPressed=> ButtonPressed2
SET 行目 TO 0
# エクセル処理完了
WebAutomation.LaunchEdge.LaunchEdge Url: $'''http://timekrei.K:8180/timekrei/login.html''' WindowState: WebAutomation.BrowserWindowState.Maximized ClearCache: False ClearCookies: False WaitForPageToLoadTimeout: 60 Timeout: 60 PiPUserDataFolderMode: WebAutomation.PiPUserDataFolderModeEnum.AutomaticProfile BrowserI業務tance=> Browser
# 分岐1
WebAutomation.PopulateTextField.PopulateTextFieldUsePhysicalKeyboard BrowserI業務tance: Browser Control: appmask['Web Page \'h ... login.html\'']['Input text 4'] Text: NewVar2[行目][0] Mode: WebAutomation.PopulateTextMode.Replace UnfocusAfterPopulate: True WaitForPageToLoadTimeout: 60
WAIT 2
WebAutomation.PopulateTextField.PopulateTextFieldUsePhysicalKeyboard BrowserI業務tance: Browser Control: appmask['Web Page \'h ... login.html\'']['Input password'] Text: P'AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAApoJvgLOqDE2Stt4d8UpAPgQAAAACAAAAAAADZgAAwAAAABAAAAC業務ZL79hy4d09VvK8Cw0CNAAAAAASAAACgAAAAEAAAACHai6oPNlPLZbqt3hjUGBMQAAAA2SD9LmUatvu2tZJVvqMQihQAAAA/DptwcNob0EU53ckAvVa7G6wHRw==' Mode: WebAutomation.PopulateTextMode.Replace UnfocusAfterPopulate: False WaitForPageToLoadTimeout: 60
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... login.html\'']['Div \'ログイン\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
WAIT 10
WebAutomation.PressButton.PressButton BrowserI業務tance: Browser Control: appmask['Web Page \'h ... edule_week\'']['Div \'実績\' 2'] WaitForPageToLoadTimeout: 60
WAIT 10
@@source: 'Recorder'
DISABLE WebAutomation.LaunchEdge.AttachToEdgeByUrl TabUrl: 'http://timekrei.K:8180/timekrei/home.html#performance_create' AttachTimeout: 10 BrowserI業務tance=> Browser
LOOP WHILE (NewVar2[行目][4]) > (0.00)
# 分岐2
WebAutomation.PopulateTextField.PopulateTextFieldUsePhysicalKeyboard BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_create\'']['Div'] Text: NewVar2[行目][1] Mode: WebAutomation.PopulateTextMode.Replace UnfocusAfterPopulate: False WaitForPageToLoadTimeout: 60
@@source: 'Recorder'
WAIT 2
MouseAndKeyboard.SendKeys.FocusAndSendKeysByI業務tanceOrHandle WindowI業務tance: Browser TextToSend: $'''{Back}{Back}{Back}{Back}{Back}{Back}{Back}{Back}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False
WAIT 2
MouseAndKeyboard.SendKeys.FocusAndSendKeysByI業務tanceOrHandle WindowI業務tance: Browser TextToSend: $'''{Return}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False
@@source: 'Recorder'
WAIT 2
MouseAndKeyboard.GetMousePosition RelativeTo: MouseAndKeyboard.MousePositionRelativeTo.Screen X=> MousePosX Y=> MousePosY
MouseAndKeyboard.MoveMouse X: 3160 Y: 300 RelativeTo: MouseAndKeyboard.PositionRelativeTo.Screen MovementStyle: MouseAndKeyboard.MovementStyle.I業務tant
WAIT 5
MouseAndKeyboard.SendMouseClick.Click ClickType: MouseAndKeyboard.MouseClickType.DoubleClick MillisecondsDelay: 0
WAIT 5
# 分岐3
UIAutomation.SetDropDownListValueInWindow.SetDropDownListValueByName DropDownList: appmask['Window \'Time Krei - 職場 - Microsoft Edge\'']['Combo Box'] Optio業務Names: NewVar2[行目][5] UseRegularExpressio業務: False
@@source: 'Recorder'
WAIT 2
UIAutomation.SetDropDownListValueInWindow.SetDropDownListValueByName DropDownList: appmask['Window \'Time Krei - 職場 - Microsoft Edge\'']['Combo Box 3'] Optio業務Names: NewVar2[行目][6] UseRegularExpressio業務: False
WAIT 2
UIAutomation.SetDropDownListValueInWindow.SetDropDownListValueByName DropDownList: appmask['Window \'Time Krei - 職場 - Microsoft Edge\'']['Combo Box 2'] Optio業務Names: NewVar2[行目][7] UseRegularExpressio業務: False
WAIT 2
UIAutomation.SetDropDownListValueInWindow.SetDropDownListValueByName DropDownList: appmask['Window \'Time Krei - 職場 - Microsoft Edge\'']['Combo Box 4'] Optio業務Names: NewVar2[行目][8] UseRegularExpressio業務: False
@@source: 'Recorder'
WAIT 2
# 分岐4
SET NewVar TO NewVar2[行目][3]
IF NewVar2[行目][2] = $'''PJ2018030800017''' THEN
WebAutomation.PopulateTextField.PopulateTextFieldUsePhysicalKeyboard BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['Input text \'search\''] Text: P'AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAApoJvgLOqDE2Stt4d8UpAPgQAAAACAAAAAAADZgAAwAAAABAAAACjYK5RYaXOodK913j7ZgAIAAAAAASAAACgAAAAEAAAAH+bwccMzQbXw0qcqWgOW10gAAAA1QdKdRatWiADSJjL2TkFRz/rELFZ0TFTbJm40uinitsUAAAAn30nMT8cS2EklxeUuj2KJfGYXHg=' Mode: WebAutomation.PopulateTextMode.Replace UnfocusAfterPopulate: True WaitForPageToLoadTimeout: 60
WAIT 5
MouseAndKeyboard.SendKeys.FocusAndSendKeysByControl Control: appmask['Window \'Time Krei - 職場 - Microsoft Edge\'']['Edit \' プロジェクト名検索\''] TextToSend: $'''{Return}{Return}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: True
WAIT 5
@@source: 'Recorder'
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['Div \'プロジェクト名を選択\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True
@@source: 'Recorder'
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'新○○\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True
WAIT 10
@@source: 'Recorder'
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['Div \'詳細を選択\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True
WAIT 2
SWITCH NewVar
CASE = 2
@@source: 'Recorder'
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'2業務(企画・提案)\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True
CASE = 2.5
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'2.5業務(要件定義)\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
ON ERROR
CALL エラー処理1
REPEAT ACTION
END
CASE = 3
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'3業務(設計(外部・内部・運用設計))\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
CASE = 4
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'4業務(プログラミング)\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
CASE = 5
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'5業務(テスト)\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
CASE = 6
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'6業務(運用引継)\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
CASE = 7
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'7業務(セットアップ)\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
CASE = 8
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'8業務(マスタ構築)\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
CASE = 9
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'9業務(マスタ変更)\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
CASE = 10
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'10業務(データ構築)\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
CASE = 11
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'11業務(データ移行)\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
CASE = 12
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'12業務(本番稼動確認)\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
CASE = 13
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'13業務(作業依頼)\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
CASE = 14
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'14業務(PM管理工数)\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
END
ELSE IF NewVar2[行目][2] = $'''PJ2021113000025''' THEN
DISABLE WebAutomation.LaunchEdge.AttachToEdgeByUrl TabUrl: $'''http://timekrei.K:8180/timekrei/home.html#performance_detail''' AttachTimeout: 5 BrowserI業務tance=> Browser
WebAutomation.PopulateTextField.PopulateTextFieldUsePhysicalKeyboard BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['Input text \'search\''] Text: P'AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAApoJvgLOqDE2Stt4d8UpAPgQAAAACAAAAAAADZgAAwAAAABAAAADZ9KpALgcGf4u4yKjvl463AAAAAASAAACgAAAAEAAAAHNZ80D0nQE4psvf+YUo6xsgAAAAbLtm1meUhWdXpVhadKU1duP86xI/4c7aQPyEZplHbWYUAAAA4GvzD+jnyugXNiOXsulErCuBfLg=' Mode: WebAutomation.PopulateTextMode.Replace UnfocusAfterPopulate: True WaitForPageToLoadTimeout: 60
WAIT 5
MouseAndKeyboard.SendKeys.FocusAndSendKeysByControl Control: appmask['Window \'Time Krei - 職場 - Microsoft Edge\'']['Edit \' プロジェクト名検索\''] TextToSend: $'''{Return}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: True
WAIT 10
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['Div \'プロジェクト名を選択\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'新○○\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True
WAIT 10
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['Div \'詳細を選択\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True
WAIT 5
SWITCH NewVar
CASE = 97
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'97有給休暇\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
CASE = 98
WebAutomation.Click.Click BrowserI業務tance: Browser Control: appmask['Web Page \'h ... nce_detail\'']['List item \'98K社内業務\''] ClickType: WebAutomation.ClickType.LeftClick MouseClick: True WaitForPageToLoadTimeout: 60 MousePositionRelativeToElement: WebAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
END
END
WAIT 5
# 詳細登録
UIAutomation.Click.Click Element: appmask['Window \'Time Krei - 職場 - Microsoft Edge\'']['Group \'common_btn common_btn_edit_submit\''] ClickType: UIAutomation.ClickType.LeftClick MousePositionRelativeToElement: UIAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
WAIT 5
# 一覧登録
UIAutomation.Click.Click Element: appmask['Window \'Time Krei - 職場 - Microsoft Edge\'']['Group \'common_btn common_btn_edit_submit\' 2'] ClickType: UIAutomation.ClickType.LeftClick MousePositionRelativeToElement: UIAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
ON ERROR
CALL エラー処理2
REPEAT ACTION
END
WAIT 5
UIAutomation.Click.Click Element: appmask['Window \'Time Krei - 職場 - Microsoft Edge\'']['Text \'登録する\' 4'] ClickType: UIAutomation.ClickType.LeftClick MousePositionRelativeToElement: UIAutomation.RectangleEdgePoint.MiddleCenter OffsetX: 0 OffsetY: 0
WAIT 5
Variables.IncreaseVariable Value: 行目 IncrementValue: 1
END
Display.ShowMessageDialog.ShowMessage Title: $'''処理が完了しました''' Icon: Display.Icon.None Butto業務: Display.Butto業務.OK DefaultButton: Display.DefaultButton.Button1 IsTopMost: False ButtonPressed=> ButtonPressed
# 処理終了
5-4.工夫点 Waitを使う
Timekreiは社内システムということもあり、VPN接続をする必要がありました。そのため、レスポンスが悪く、WEBの処理が追い付いていないためエラーになりました。
そこで、Waitを使うことにより、PowerAutemateDesktopの処理時間を調整し、エラーが解消されました。
6.動作
1回の実行で1日分の作業をWEBに自動入力する処理が完成しました。
エクセルの読み込みからログインまでの処理
作業を入力する処理
7.使ってもらった
私は日ごろから10人ほどの朝会チームミーティング時に情報共有を行っているのですが、今回開発した内容も同様に5分前後で経緯と概要、動作の動画を使って自動化における利便性を説明しました。以前とは違い説明だけでなく使ってもらいたいということも伝えました。
使ってもらうやり方としては、作ったフローを各自で実施してもらうことは今回せず、2回のエクセル入力期間を設けて、自動入力希望された2名分について実施しました。また、意見も伺いました。
Aさん
チームリーダでこの開発の原点として、待ち望んだ人からのコメントになります。
コメント
・ほんとに作るとはすごいね。便利だと思う。
・今回は1回の実行で1日分の作業が入力できるということだが、ゆくゆくはもう少し拡大していければよい。
・ちなみにこれのコストはどれくらい?
・これをきっかけにTimekreiに限らず、他の処理も自動化していってほしい。
Bさん
チームメンバーで比較的積極的な人からのコメントになります。
コメント
・エクセルを作成するのは大変だと思うが、1か月分さえ作れば少し変えるだけで後続の月でも作業が減らせそう。
その他の方
雰囲気
・何かすごいことをしているんだな。
・ログインのパスワードを教える必要があり、変更なども必要になるので、様子見。
感想・気づいたこと
開発して満足ではなく、使ってもらうまでがゴールなのだと感じました。
Timekreiにとどまらず、他の自動化もよいとは思いますが、特定の人に効果がある開発ではなく、ある程度多くの人の不満に効果がある開発の方が、反響も大きのだと感じました。また、今回パスワードの障壁が少しあったので、そこも減らしていくことが必要だとも感じました。
8.次は1か月分まるっと処理!
今回は、1日分の作業をWEBに自動入力する処理を作成しました。
初めてRPAに挑戦し、また一つ経験が増えました。2日分の作業を入力すると処理の最後にエラーとなってしまったので、もう少し改良の余地がありそうです。今後も開発していきたいと思います。そして最終的には1か月分×チームメンバー全員の入力を実施したいと思います。
最後まで読んでいただき、ありがとうございました!
追記(この記事を拝見した方からのコメント)
以下のありがたいコメントがありましたので、抜粋してご紹介いたします。
・今回実施したあなたの作業は「資産である」と思いました。
・1ヶ月分まるっと自動化できるのも時間の問題なのでは!?と思いました💡
続編も期待してます📣
・トライ&エラーで進めていて、実用化、楽しみにしています!
前向きなコメントをいただきありがとうございました。これからも頑張りたいと思います。
2024年8月7日 作成
2024年8月12日 修正