夢はAIに乗せてPart2

前回の記事に

たくさんの反響とコメントをXにていただきました。本当にありがとうございます。

前作を権利侵害しないバージョンに改造し、皆で遊べるようにしてみたお話です。

まあ、ポエムだと思って読んでください。

 

まずはデータソースを使用しないでもいいように

選手名と画像をコレクションに格納する方式に変更です。

*画像はLenardAIで作成

 

用意するのはTextInputと画像の追加、そしてボタンです。

ボタンには以下のようにコレクションを作るよう仕込みます。

Collect(colmaster,{name:TextInput2.Text,image:UploadedImage1.Image});



では対戦させてみましょうか

 

今回はプロンプトで遊んでみます

"以下の例に倣って試合概要と試合結果を作成してください
また、技の名前はPowerAppsやエクセルの関数の名前で作成してください。
【制限事項】勝敗は必ず決めること、結果は必ず表示すること、PowerAppsやエクセルの関数を技名に使うこと、結果は勝者の名前だけとすること。

例:アントニオ猪木三沢光晴の試合概要と結果
結果:メインは特別試合としてアントニオ猪木が、三沢光晴と初の一騎打ち。三沢のエルボーの前に、猪木は苦しい戦いを強いられる。終盤、三沢は豪快なタイガードライバー91で叩きつけるも、猪木はカウント3寸前でキックアウト。ならばと三沢は必殺のエメラルドフロウジョンを狙うが、猪木は魔性のスリーパーに切り返して激勝。白星スタートに成功した。試合後、猪木は「鶴田、天龍、小橋、誰でもかかってこい!」とアピールし大会を締めくくった。
勝者:アントニオ猪木

例:アントニオ猪木三沢光晴の試合概要と結果
結果:メインは特別試合としてアントニオ猪木が、三沢光晴と初の一騎打ち。三沢のエルボーの前に、猪木は苦しい戦いを強いられる。終盤、三沢は豪快なタイガードライバー91で叩きつけるも、猪木はカウント3寸前でキックアウト。ならばと三沢は必殺のエメラルドフロウジョンを狙うが、猪木は魔性のスリーパーに切り返す。三沢はならばとローリングエルボーの乱れ打ち、猪木をフォールし白星スタートに成功した。試合後、三沢は「猪木さん、また戦いましょう」とアピールし大会を締めくくった。
勝者:三沢光晴

例:ジャンボ鶴田前田日明の試合概要と試合結果
結果:スペシャルマッチとして、ジャンボ鶴田前田日明が激突。鶴田のインサイドワークをはねのけるように、前田は持ち前のキックで猛攻。さらに相手のお株を奪うジャンピングニーまで繰り出す。終盤、鶴田はジャンボラリアットからバックドロップを狙うも、前田は膝十字固めで切り返す。それでも鶴田は必死に反撃するが、前田は大車輪キックで動きを止めると、最後はキャプチュードで豪快勝利。試合後、前田はマイクアピールを握り、「誰が一番強いのか、この大会で決めればいいんや」と大会を締めくくった。
勝者:前田日明

"& First(colred).name & "と" & First(colblue).name & "の試合概要と試合結果
結果:"

 

さてどうなる?



うーんカオスですねえ、まあ面白いからいいや

 

権利侵害をしないために画像も作りますか!!

作りますよ、作ればいいんでしょ

ということで、プレミアムコネクタ作成

レスラーの名前はAzureOpenAI任せ

画像はDALL-E任せ

しかし最強のレスラーを作ると高頻度でタイタンデストロイヤーという名前になるのはなぜなのか・・・(笑)

でRegisterボタンにコレクション作成を仕込む

Collect(colmaster,{name:TextInput4.Text,image:Image1.Image});

無事追加されてますね

 

うーん、レジスタンス関数とはこれいかに(笑)反逆のdai365なのか?

 

一応リーグ戦も作ったので

どこかのコミュニティで大会でもやりませんかね(笑)

みなさん、名前と画像持ち寄りで

 

と思ったんですが、生成画面、同じ画面でいいですよね(笑)

それと日本語だと画像ちゃんと作ってくれないのでフローも追加

Set(response,テキストの翻訳.Run(TextInput2.Text).restext);
Set(varImage,ImageGenerator.ImageGenerator("pro-wrestler named" & response,1,"512x512"))

こんな感じにして

ふぅ、スッキリしましたね

ということで肖像権問題クリア?した気がします。

PowerAppsのPDF関数使ったことありますか?

PDF関数を使うとこんなことできます

 どうも、dai365です。いつもポエムばかり書いていますので、今回は関数ポエムを書いてみたいと思います。

 ところで皆さんはPDF関数を使ったことはありますか?この機能、試験段階なんですけど、私は出始めからめっちゃ気に入って使っています。

 特に帳票周りでは威力ものすごいです。とはいえ、試験段階当初は相当文字化けしてましたし、今は私の運用においては実害がないレベルなのでこうして記事化しようと思った次第です。(最後にオチが待ってます)

 ちなみにポエマーなので何が文字化けするかとかの検証はその道の方にお任せします。今年の初めに検証した時点では数字大文字がNGだった記憶があります。

 

 この関数使うと、画面全体とかギャラリーだけとかをPDFにすることが出来ます。

 私がよく多用するパターンは以下の2つ

 

➀ギャラリーを含む画面全体をボタン押したらOutlookの添付ファイルにして送信

➁ギャラリーを含む画面全体をボタン押したらSharepointに保存

 

まあ、私が考え出したわけでもなんでもなく、いつものようにRezaさんのおかげです。

www.youtube.com

この動画、何度見たことか(笑)、まさに私のバイブルです。

 

以前やってみたこと

 いや、PDF関数でしょ、動画のとおりに写経しただけでしょ、そんな声が聞こえてきそうですね(笑)、実際そうなんですけどね。

 実は、今年の春先にとある日報アプリをリリースして、リリースして一月ほどたったところでこんな問題が起きました。

 当初の私の想定はひと月=多くても25営業日程度、なら25行で十分⇒1ページの想定でした。
 それがですね、ひと月になんとなんと70回=70行もある場合があることに気づいたんです。

 もちろん最初からPDF関数使って作りこんでましたので、1ページにボタン一つしか作ってませんよね、でもそれでは26行目以降はちゃんと印刷されない・・・

 さて、どうしたものか・・・ということで、このときはベタに最大4ページなら4画面作って遷移すればいいと思いそのような対応をしました。

 まあ、これはこれで動作もしますし、何ら問題もないのですが・・・

 

今回やってみたこと

 前回やったときにベタにページ数の分画面を作るというなんとも泥臭い解決方法しか思い浮かばなかったもので・・・

 今回は1画面の中で完結させることにチャレンジ!!
 今回のネタは年末恒例の有馬記念の暦年結果表示!!

しょーもないネタですねえ(笑)、しかもこんなのPDF化してどうしようと、まあそこは皆さんお使いの帳票だと思って見てやってください。

 

まずは画面のOnVisibleに変数設定します。

 

で変数切り替え用に-ボタンを設置して以下のように

次にギャラリーにフィルターかけてみましょう

これで-ボタン押せば、開催年は切り替わりますね

➀メールの添付ファイルとしてPDFを送信する場合

SharepointにPDFとして作成する場合

これはフロー必要なので以下のような感じ

まあ、このあたりはRezaさんの動画まんまですね

今回のチャレンジ!?

 今回チャレンジというか、いやそれ難易度全然低いだろというお試しを一つしてみました。

 春先の私のレベルはページごとに画面作っちゃうようなレベルです。でも今回は変数を用意してみました。

 でベタにこう書いてみました。

 何のことはないPDF作成する、変数更新する、PDF作成する、を繰り返しています。

例によって回数はベタに書きます。

 これ、ちゃんと動くんですよ(笑)

 正直、ページ数が限定されているのならこれでもいいのかなあと、実装する際にはif文かswitchで書くと思いますが。

 

 で、ですね、こんなの恥ずかしいよなあと思いながらforall sequenceを試してみたんですが・・・

 

 

UpdateContext関数はこういうことらしいですね。

 

どうにかして連続印刷してみたい

とある方のアドバイスによりコレクションを使ってみました。

変数からコレクションに方針変更です!

まずは画面のOnVisibleにこんな感じで仕込みます。

ギャラリーのフィルターもこんな感じに

でこんなふうにボタンに仕込んでみました

今回のデータは有馬記念31年分の結果が格納されています。

つまり31回繰り返せば全ページ印刷するという算段です。

フロー走らせて、コレクションの値を1つ減らす(ここは用途に応じて)
さあ、上手く動くでしょうか?

 

順調に作成されてますね。どうやら上手くいったようです。

最後の1回Updateif余計かもしれませんね、1991年分はデータないので(笑)

まあ、そのへんはどうにかしましょう。

いずれにせよ1画面完結のPDF作成がこれにて完成ということで今回は終わります。

と思いきや・・・

問題発生

とあるアプリを作成していたら、あれれ?全角英数字表示されないやん

あらまあどうしましょう、ということで策を練る・・・

いやー慌てましたねえ、なんせ住所必須のアプリですから・・・

このままじゃあマンションの部屋番号全くわかりませんからね(笑)

ということで強制変換を試みる

この記事、お世話になりました。

note.com

ということで無事解決・・・したんだよなホントに

 

つづき

うーん、有馬記念のデータはたまたま年って列があったから減算できたけど、普通はそうはいかないよなあ、ということで

ClearCollect(ct,1);ClearCollect(colyear,Distinct(arimadata,year));ForAll(colyear,Collect(colnumber,{year:ThisRecord.Value,no:CountRows(colnumber)+1}))

ctはカウンター代わりの変数

colnumberにはnoに1からの連番の値、yearには年の値があるだけ入ります

 

でそれを動かしたうえでギャラリーには

Filter(arimadata,year=Last(FirstN(colnumber,First(ct).Value)).year)

でPDF作成ボタンには

ForAll(Sequence(CountRows(colnumber)),PDF作成.Run({file:{name:Last(FirstN(colnumber,First(ct).Value)).year&"arimadata.pdf",contentBytes:PDF(PDF,{Orientation:"Landscape"})}});UpdateIf(ct,Value=Value,{Value:Value+1}))

 

無事出来たようです

拙い関数ですが、どうにか作成することが出来ました。

ということで関数ポエムでした。

夢はAIに乗せて

まず初めに

この内容は、個人利用目的であり

商用利用や権利侵害を目的としたものではありません。

1ファンの長年の夢をたまたまPowerAppsを使って具現化したものだという点にご理解をお願いいたします。

 

このアプリ作成を決意したキッカケ(無茶?)

JPPGB#6にて、しょぼいビンゴカードゲームで登壇させていただき

その後、【JPPGB】ゲーム作成コンテスト #0の凄まじい内容に驚愕

大賞を受賞したヨウセイさんの「青春を溶かしたパチスロ

という言葉に感銘を受ける。

そう、私にとっての「青春を溶かした」ものとは?

 

そう、それはプロレス

何を隠そう、プロレスファン歴40年超(笑)

所持しているプロレス動画は2,800ファイル、4TB、全て動画化

(ちなみにビデオ300本、DVD1500枚あった)

実家には週刊プロレス週刊ゴング他4,000冊が眠る

生まれも育ちも北海道だが、プロレス見たさに関東の大学へ進学

結果、4年間で54回観戦

今から30年前の1993年、新日本プロレスG1両国7連戦は完全制覇した

そして、夏といえばG1クライマックスの季節

 

プロレスの魅力って何?

力道山に始まり、馬場、猪木と受け継がれた日本のプロレス

そこには選手の離合集散が幾度も繰り広げられた。

なぜレスラー達は団体を旗揚げし、そしてまた離散するのか?

それは誰もがトップに立ちたいという野望があるからである

デビューしながらに将来のエースを確約された者

長年に渡って負け役(ジョバー)を任されてきた者

誰しもが日の当たる世界を目指して闘う

そしてそこにはジェラシーと裏切りが、人間そのものな世界

それがプロレス

 

7月15日夜(ゲームコンテスト終了後)

大いに盛り上がったゲームコンテストの夜

【JPPGB】ゲーム作成コンテスト #0 - connpass

みんなすごいなあ~、自分も何か作ってみたいなあ~

作るならプロレスのゲームだよなあ~

と思い立つ

まずはG1クライマックスの季節も近いし、リーグ戦出来ねえかな

と思いながらパワスロを回す

 

リーグ戦って対戦表必要だよね

対戦表ってどうやって作るんだよ~

ギャラリー使うよなあ、きっと・・・・

と途方に暮れていた私の脳裏に、JPPGB#6の光景が

ふらりさん、Gallery in Galleryで座標マップとか作ってたなあ・・・
https://www.docswell.com/s/fworlddocs/5YWMW9-2023-06-24-155843#p7

よし、まずはやってみますか!!

 

レスラー選んで、ボタン押したらリーグ戦のカード決定!!

ForAll(
    Sequence(CountRows(colleague)) As PositionY,
    ForAll(
        Sequence(CountRows(colleague)) As PositionX,
        Collect(
            colCard,
            {
                cell: Text(PositionY.Value) & "-" & Text(PositionX.Value),
                card: Index(
                    colleague,
                    PositionY.Value
                ).name & " - " & Index(
                    colleague,
                    PositionX.Value
                ).name,
                card2: Index(
                    colleague,
                    PositionY.Value
                ).subname & " - " & Index(
                    colleague,
                    PositionX.Value
                ).subname,
                redcorner:Index(colleague,PositionY.Value).name,
                bluecorner:Index(colleague,PositionX.Value).name,
                result: "",
                detail: "",
                PositionY:Text(PositionY.Value),
                PositionX:Text(PositionX.Value),
                 id:LookUp(colindex,cell=Text(PositionY.Value) & "-" & Text(PositionX.Value),id),
                location:LookUp(colindex,cell=Text(PositionY.Value) & "-" & Text(PositionX.Value),location)
            }
        )
    )
);

あれだけ苦手にしていた配列のはずなのに・・・・・

やはりプロレスゲームを作りたい力が何かを生んでいるのか??

 

まず、基本形が完成

レスラー選択⇒レスラーマスターから10人選ぶ、ボタン押す

ギャラリーにリーグ戦の試合が表示される

10人だと10×9/2=45試合

*座標でやったのでフィルターで余計な試合を省ける

Filter(colCard,Value(PositionY)<Value(PositionX))

がこれはのちにこれでは物足りなくなる・・・

 

さあ、対戦だ!!

まあ、試合はGallery〇〇.Selectedでいけちゃうよね

さてはて、勝敗どうやって決めよう・・・・・

パラメーターもいいけど、絶対偏るよなあ・・・・

たぶん、天龍とか最強にしちゃう気しかしない(笑)

 

ここで思い出したのが

私の特技というか趣味は、大人の工作という名の写経(笑)

このころもyoutubeギークフジワラさんのチャンネルで作成していたプライベートChatGPTがあった

https://www.youtube.com/watch?v=jERrUWTm7nA

それに春先にOpenAIのAPI叩いて遊んでたしなあ

このときはQiitaで益森さんの記事参考にしたよなあ

https://qiita.com/Takashi_Masumori/items/96b9e0f1590762fd6fad

でもなあプロンプトとかよくわかんねえしなあ・・・

 

まずは普通にChatGPTに投げてみた

Few-shot Learningっていうのかふむふむ・・・

俺はプロレスマニア、例文ならいくらでも作れるぞ(笑)

 

まあ、結果帰ってきますよね、普通に

接続も春先に作ったお遊びコネクタとフローもあるし、いけるだろ

 

みなさんのおかげです。ホント

こんな50のオジサンがこんなことできるの、Youtubeや皆様のおかげです

 

何気に苦労した気がするのが星取表

先ほども言ったようにこのリーグ戦は座標でやってます。

つまり1-2の対角は2-1

1-2が〇なら2-1は✕、これを格納しないと点数出せない

UpdateIf(colCard,cell=Text(GalleryMatch.Selected.PositionY & "-" & GalleryMatch.Selected.PositionX),{result:winner,detail:detail2},cell=Text(GalleryMatch.Selected.PositionX & "-" & GalleryMatch.Selected.PositionY),{result:winner,detail:detail2})

とコレクションに結果と試合詳細を戻してあげて

*最初Patchでやったけど挙動が安定しなかったのでUpdateIfに変更した。

CountRows(Filter(colCard,result=ThisItem.name))これを数えれば勝ち点2

 

いや、だからGPTなんだから結果は返ってくるって

ここでハタと気づきます。

勝敗判定どうやってやんのよ?・・・と

リーグ戦だよ、星取表作りたいよね?得点もわかるようにしたいよね?

と悩んだ結果

UpdateContext({winner:Right(Label8.Text,Len(Label8.Text)-Find("★",Substitute(Label8.Text,":","★",Len(Label8.Text)-Len(Substitute(Label8.Text,":","")))))}

勝者:〇〇と最後にGPTに出力させて、そこを抜き出して変数に格納

なんというエクセル風味な解決方法

たまーにおかしな挙動するときあるけど、まあ愛嬌(笑)

 

ふう、できたできた





正直、これだけでもプロレスファンにとっては十分に遊べます

実際、完成した夜、思い切り時間溶かしました(笑)

 

いや、ここまでできたんだからさ・・・

出戻りガツオさんがText to Speechとかやってたなあ、あれやってみたいなあ・・・

https://qiita.com/DEmodoriGatsuO/items/37ee57af6fa62e4a7831

でもなあ、出来るかなあ、やれるかなあ・・・ということでチャレンジ!!

フロー自体は難なく完成

がしかし、応答が音声??

どうやんのこれ

思わず出戻りガツオさんにDM

ありがとうございました!!

Set(audio,Text_to_Speech.Run(LabelDetailLeague.Text))

この格納が難敵でした(笑)

 

試合結果も出来た、さあ次は

うーん、もっと雰囲気出したいなあ、やっぱさプロレスはテーマ曲だよ!!

どうせ個人利用しかしないし、ということで

プロレスファンは季節ごとに身体が反応する曲があります

またイントロを聞くだけで血がたぎる曲があります

これ搭載してから、余計に時間溶けるようになりましたね(笑)

聞いちゃうんですよ、ずっと

 

ちなみに登場するレスラーはというと

初期段階では歴代IWGP、三冠、GHCのメジャー3大タイトルの歴代王者としていた。(60人ちょい)

がしかし、そんなものでは飽き足らずに、すぐに180人に拡大(笑)

これにより力道山以降の主要レスラーはほぼ網羅

たぶん、現役選手よりも物故者のほうが多い

プロレスファンはそれを「あの世プロレス」と呼び、夢のカードを夢想する

 

いや、これシングルリーグだけじゃもったいない

最初はシングルのリーグ戦しか作ってなかったんですね

でもこれ全部終わらせるのに45試合やるんですね(セーブ機能作れよ、おい)

通勤時間にやると、マジ時間溶けます(笑)、優勝決まるまでやっちゃうやつです

もっとライトに楽しみたいときってありますよね

ということでシングル戦とタッグ戦追加!!

とここで初めてメニュー必要じゃね?となる

 

実装してみたかったんですよ、このメニュー

ハイ、またまた大人の工作です

とある土曜日のことです。何気にYoutube見てたら、Akiraさんがライブやってるじゃないですかあ

見ちゃいましたよ、ずっと

https://www.youtube.com/watch?v=5vEkFcDWZRE&t=2186s

と同時に即座に写経開始(笑)

やってみたかったんですよねえ、ギャラリーで作るメニュー

Akiraさん、続きよろしくお願いします!

今現在のメニューはコチラ

増え続けるやりたいこと

シングルリーグ戦に始まり、シングル、タッグと実装

ここまできたらタッグリーグ戦でしょお!!

これがねえ、配列苦手おじさんはしばし考えましたよ(笑)

Clear(coltagleague);

Collect(coltagselect,FirstN(Shuffle(Filter(WreslerMST,IsBlank(team))),20));

ForAll(Sequence(10,1,1),Collect(coltagleague,{name:First(coltagselect).name & "・" & Index(coltagselect,2).name,subname:First(coltagselect).subname & "・" & Index(coltagselect,2).subname,name1:First(coltagselect).name,name2:Index(coltagselect,2).name});Remove(coltagselect,First(coltagselect));Remove(coltagselect,First(coltagselect)));Clear(coltagselect)

20人選んで、タッグ組ませて、2人消して、またタッグ組ませるを10回

最初Sequence(10,1,1)が書けずに10回書いたことはナイショ(笑)

 

プロレスにはさ、こういうのもある

シングルリーグ戦に始まり、シングル、タッグ、タッグリーグ戦も実装

次何にしようかなあ~

あ!!試練の10番勝負作ろ(軽っ)

というノリで試練の10番勝負も完成

相手だけ変えたい場合にも対応(笑)



時は1988年8月8日、横浜文化体育館

この年、4月に飛龍革命が勃発し、当時IWGP王者は藤波辰巳

猪木は背水の陣で弟子である藤波に挑む

実況はすでにプロレス実況を離れていた古舘伊知郎

真夏の酷暑の中、試合はなんと60分フルタイム引き分けに

試合後、猪木を長州が肩車、猪木の目には涙が光っていた・・・

このテレビ中継のラストに流れたのが、この名曲

そうサザンオールスターズ「旅姿6人衆」

35年前のあの日、藤波は猪木を60分独り占めにした・・・

プロレスとはつくづく記憶のスポーツ

ということでMemorialコーナー設置

 

やりたいことがそこにはあった・・・

7月26日、私はとあるコミュニティに初参加します。

そうです。おうじゃさんといっしょです!!
https://oujasan-to-issho.connpass.com/event/290808/

ここでVoiceVoxというものの存在を知ってしまいます(笑)

https://voicevox.hiroshiba.jp/

18番を指定(指名?)すると、そこには・・・・

いやあ、頑張りましたよ、このときは

なんせ声がね〇〇りボイスなんですよ

https://koruneko.hatenablog.com/entry/2023/04/17/022837

コルネさんの記事も参考にしつつ

 

機能拡張というか、マニアックな方向に・・・

かつてプロレスの興業があると、電柱にポスターが貼られていました。

ハイ、昭和の時代の光景です。

ですが、あのポスターを見ると、わくわくしたものでした。

特に好きだったのが、世界最強タッグ決定リーグ戦のポスターでした。

うーん、こういう機能がプロレスゲームには欲しいよなあとか思いながら作成(笑)

基本的にギャラリー使うんですが

表示したい場合と、そうじゃない場合がある

要はテーブルにそれを指定してあげればいいんですね

[
    {
        id: 1,
        name1:Index(coltagleague,1).name1,
        name2:Index(coltagleague,1).name2,
        image1:LookUp(MST,name=Index(coltagleague,1).name1).image,
        image2:LookUp(MST,name=Index(coltagleague,1).name2).image
    },
    {
        id: 2,
        name1:Index(coltagleague,2).name1,
        name2:Index(coltagleague,2).name2,
        image1:LookUp(MST,name=Index(coltagleague,2).name1).image,
        image2:LookUp(MST,name=Index(coltagleague,2).name2).image
    },
    {
        id: 3,
        name1:Index(coltagleague,3).name1,
        name2:Index(coltagleague,3).name2,
        image1:LookUp(MST,name=Index(coltagleague,3).name1).image,
        image2:LookUp(MST,name=Index(coltagleague,3).name2).image
    },
    {
        id: 4,
        name1:Index(coltagleague,4).name1,
        image1:LookUp(MST,name=Index(coltagleague,4).name1).image
    },
    {
        id: 5
    },
    {
        id: 6,
        name2:Index(coltagleague,5).name1,
        image2:LookUp(MST,name=Index(coltagleague,5).name1).image
    },
    {
        id: 7,
        name1:Index(coltagleague,4).name2,
        image1:LookUp(MST,name=Index(coltagleague,4).name2).image
    },
    {
        id: 8
    },
    {
        id: 9,
        name2:Index(coltagleague,5).name2,
        image2:LookUp(MST,name=Index(coltagleague,5).name2).image
    },
    {
        id: 10,
        name1:Index(coltagleague,6).name1,
        name2:Index(coltagleague,6).name2,
        image1:LookUp(MST,name=Index(coltagleague,6).name1).image,
        image2:LookUp(MST,name=Index(coltagleague,6).name2).image
    },
    {
        id: 11
    },
    {
        id: 12,
        name1:Index(coltagleague,7).name1,
        name2:Index(coltagleague,7).name2,
        image1:LookUp(MST,name=Index(coltagleague,7).name1).image,
        image2:LookUp(MST,name=Index(coltagleague,7).name2).image
    },
    {
        id: 13,
        name1:Index(coltagleague,8).name1,
        name2:Index(coltagleague,8).name2,
        image1:LookUp(MST,name=Index(coltagleague,8).name1).image,
        image2:LookUp(MST,name=Index(coltagleague,8).name2).image
    },
    {
        id: 14,
       name1:Index(coltagleague,9).name1,
        name2:Index(coltagleague,9).name2,
        image1:LookUp(MST,name=Index(coltagleague,9).name1).image,
        image2:LookUp(MST,name=Index(coltagleague,9).name2).image
    },
    {
        id: 15,
       name1:Index(coltagleague,10).name1,
        name2:Index(coltagleague,10).name2,
        image1:LookUp(MST,name=Index(coltagleague,10).name1).image,
        image2:LookUp(MST,name=Index(coltagleague,10).name2).image
    }
]



こんな感じですね

試合終わった後って、取材するよなあ・・・

既に満載なんですが、寝る前になると次から次へと妄想が湧いてきます

今回はやはりAI搭載がウリなので、もう一ひねりしたいところです。(いやもう十分だろ)

試合が終わったら、控室でプロレス専門誌記者が取材しますよね。

ハイ、インタビュー機能を実装してみました(笑)

意外と簡単にそれっぽくできました。

勝者と試合概要は対戦画面ですでにあるので、それを使ってロールプレイ風にプロンプトを投げる

"あなたは" & winner & "です。" & detail2 & "を踏まえてインタビューに答えてください" & TextInput3.Text &"【制限事項】選手の発言だけで返信してください。プロレスラーらしく発言してください。"



インタビューして、テキスト返して、text to speech

 

プロレスといえば東スポ!!

さらに、寝る前になると次から次へと妄想が湧いてきます

今回はやはりAI搭載がウリなので、もう一ひねりしたいところです。(いやもうホントにいいだろ)

プロレスといえば東スポです。

あの衝撃的な見出しにワクワクしたものです。

東スポ作るには、見出しと記事が必要です。

私の今回のやり方だと、プロンプトに対する回答は常にコレクションのFirstにあります。

ということはコレクションを表示させたままだと、プロンプトを複数投げると、変わってしまいます。

ということはどこかに格納してそれを表示させる必要があります。

上が見出しを作成して、格納。下が記事を作成して、格納。

新聞出来たら、表示するって算段です。

Set(varResponse,ChatGPT.SendUserMessage(Collect(_messages,{role:"user",content:NewsPrompt.Text}),{model:"gpt-3.5-turbo"}));
Collect(_messages,First(varResponse.choices).message);
UpdateContext({midasi:Last(_messages).content});
Set(varResponse,ChatGPT.SendUserMessage(Collect(_messages,{role:"user",content:NewsPrompt2.Text}),{model:"gpt-3.5-turbo"}));
Collect(_messages,First(varResponse.choices).message);
UpdateContext({kiji:Last(_messages).content});
UpdateContext({fight:true});

当然のことですが、マスター管理も必要

すでにレスラーの数ふくれあがってるんですが・・・マスター管理メニューも作りましょう

ということで再び益森さんの記事にお世話になりました。

https://qiita.com/Takashi_Masumori/items/a1c0f6f557605b91a596

まあ、サクっとできたんですが、アレ?これ新規登録ないのかあ

じゃあ作るか、と思ったときにまた思い出してしまうんですね・・・余計なことを

灯台下暗し

8月5日のことです。土曜日と言えば「気ままに勉強会」です。

この日は、いつもお世話になっていて、また今回のきっかけともなったヨウセイさんの登壇。

内容はさすがの内容。

ところが、私が驚いたのは最後に実演したcsv取り込みフロー

界隈の方々が驚愕したことにも驚きましたが

それよりなにより、「あ、このアプリ買ったじゃん、会社で。持ってるし(笑)」

半年前に部下が欲しいと言ったので言われるままに買わせていただいたんですね。

当時は読解など無理でしたが、今見てみると・・・ふむふむ、こういうことね

ちなみにヨウセイさんとは

昨年の春ごろ、FacebookのJapan Power Apps User groupにて

当時、初学者の私はしょーもない質問を何度も書き込む

それに懇切丁寧に答えてくれたのがヨウセイさん

昨年の秋ごろ、何か恩返しがしたいと思い、所属されている会社にメール(仕事として)

そこから仕事でもお付き合いが始まり、技術指導を受けること数回

そのたびに、ワンランク上のアプリ開発を教えていただいております。

本当にいつもお世話になりっぱなしです。

まあ最小限アップできればいいかな

 

まあ、もういいでしょう、このへんで(笑)

BGM、めっちゃこだわりました()

*あくまで個人利用しかしておりません。

 

お盆明け、なんかやり始めたぞ、また(笑)

いや、だってさ登壇9月9日(土)でしょ、まだ3週間あるじゃん(笑)

もう一ひねりしないと、皆さん納得してくれませんよ・・・

やるなら徹底的にでしょ、という心の声が聞こえてきた

ということでMemorialコーナー拡充!!!

なんといっても私には2800ファイルの過去動画がある!!

なんか切り出し始めちゃったよ、時間溶ける溶ける

 

プロレスラーって活舌悪いんですよね

動画切り出したらmp3化は楽勝なので、じゃやってみましょうか

今度はSpeech to Textの実装です。(もはやバカ)

しかも春先にRezaさんのyoutubeみながらコネクタ作ってあったし

(いや、ちゃんとAzure使えよ、とツッコミたくなる)

うーん新キャラ作りたいときもあるよなあ

今回のテーマは生成AI搭載がウリです。(いやもういいってホント)
マスターにNewって作ったよな、あれGenerateにすっか

ということでGPT画面も追加

生成AIって文字だけじゃないよなあ

せっかくゲーム作ったんだからロゴ欲しいよなあ

いや、俺デザインセンスないし(笑)

ということでLeonard.AI使ってみました

なんとなく週刊ゴング創刊号に見えるのは、気のせい?

リーグ戦の闘う順番、巡業風にしたいよなあ

10人参加ですと公式戦は45試合

ただ並べるだけじゃ面白くない

やっぱ、興行巡業風に並べてみたい!!

ということで、組み合わせ順を追加

ClearCollect(colindex,{id:1,cell:"1-2",location:1},{id:2,cell:"3-4",location:1},{id:3,cell:"5-6",location:1},{id:4,cell:"7-8",location:1},{id:5,cell:"9-10",location:1},{id:6,cell:"1-3",location:2},{id:7,cell:"2-4",location:2},{id:8,cell:"5-7",location:2},{id:9,cell:"6-10",location:2},{id:10,cell:"8-9",location:2},{id:11,cell:"1-4",location:3},{id:12,cell:"2-5",location:3},{id:13,cell:"3-8",location:3},{id:14,cell:"6-9",location:3},{id:15,cell:"7-10",location:3},{id:16,cell:"1-5",location:4},{id:17,cell:"2-6",location:4},{id:18,cell:"3-10",location:4},{id:19,cell:"4-8",location:4},{id:20,cell:"7-9",location:4},{id:21,cell:"1-6",location:5},{id:22,cell:"2-7",location:5},{id:23,cell:"3-9",location:5},{id:24,cell:"4-5",location:5},{id:25,cell:"8-10",location:5},{id:26,cell:"1-7",location:6},{id:27,cell:"2-9",location:6},{id:28,cell:"3-5",location:6},{id:29,cell:"4-10",location:6},{id:30,cell:"6-8",location:6},{id:31,cell:"1-8",location:7},{id:32,cell:"2-3",location:7},{id:33,cell:"4-9",location:7},{id:34,cell:"5-10",location:7},{id:35,cell:"6-7",location:7},{id:36,cell:"1-9",location:8},{id:37,cell:"2-10",location:8},{id:38,cell:"3-6",location:8},{id:39,cell:"4-7",location:8},{id:40,cell:"5-8",location:8},{id:41,cell:"1-10",location:9},{id:42,cell:"2-8",location:9},{id:43,cell:"3-7",location:9},{id:44,cell:"4-6",location:9},{id:45,cell:"5-9",location:9});

ベタにやりました(笑)、いい方法あったら教えてください

うーん、リーグ戦消化したら必ず課金かぁ

リーグ戦には正直消化試合というものがある。

スキップモードもしくは自動モード欲しいよなあ(いやだからこれは遊びだよね(笑))

ということでしばし思案

Select( Parent );Set(win,RandBetween(1,2));UpdateIf(colCard,cell=Text(ThisItem.PositionY&"-"&ThisItem.PositionX),{result:If(win=1,ThisItem.bluecorner,ThisItem.redcorner),detail:"SKIP"},cell=Text(ThisItem.PositionX&"-"&ThisItem.PositionY),{result:If(win=1,ThisItem.bluecorner,ThisItem.redcorner),detail:"SKIP"})

単純にランダムに勝敗ってやつですね、まあ時短にはなります。

なんですが、これだけで進行すると、マジつまらない

改めてAIの付加価値を思い知る。

 

いや、つまらんって言ったよね、あんた

消化試合をポチポチするのにすら飽きてきて(おい!!)

うーん、一括消化してえよなあとかすぐに思う怠惰な私

じゃあ作るよ、作ればいいんでしょ、と半日

意外とこれ試行錯誤しましたねえ・・・数学苦手なんですよ、マジで

UpdateIf(colCard,Value(ThisRecord.PositionY)<Value(ThisRecord.PositionX),{result:If(First(Shuffle(["1","2"])).Value="1",ThisRecord.bluecorner,ThisRecord.redcorner),detail:"SKIP"});
UpdateIf(colCard As C,Value(C.PositionY)>Value(C.PositionX),{result:LookUp(colCard,cell=Text(C.PositionX&"-"&C.PositionY),result),detail:"SKIP"})

気に入らない結果は即座に塗り替えるwww

 

ここまでの話でおわかりのように、このゲーム権利関係は一切考慮しておりません。

なので、永遠に私の個人遊戯となります。(笑)

 

このゲーム、プロレスファンはどう楽しい?

夢のカードが死ぬほど実現するので、時間が溶けまくる

特にリーグ戦のランダムボタンは大会の妄想をものすごく膨らませる。

たまに超豪華メンバーになったリーグ戦は思わず開催してしまう

優勝が気になるので、優勝者確定するまでやってしまう(セーブ作れよ、おい)

*なのでスキップボタン実装した(笑)

メモリアルメニューで延々と想い出にふけりながら旅姿6人衆を聞いてしまう

類似事例で、ずっとオリンピア、ずっとUWFメインテーマとかもある(笑)

動画無限ループはさらにヤバい。

検証と通勤時間に遊んでいたらOpenAIの請求が

やればできるけど、時間溶けるからやらない機能

すでに機能的には満腹気味なので9月の時点でははやっていませんでしたが

また気が向いたら追加搭載する(かも)しれない機能

・対戦方式の拡充  ⇒柔道方式の勝ち抜き戦

⇒9月の登壇後に実装

・タイトル戦機能  ⇒シングル、タッグめんどそう

⇒9月の登壇後に実装

・試合概要の精度向上  ⇒週プロやゴングをadd your dataにぶち込んで・・・(もはやバカ)

・選手セレクトでテーマ曲⇒だから~権利関係がさあ

・対戦履歴を考慮した回答⇒一応履歴は残してあるけど、どうでもいいんじゃね

 

おわりに

まさか7月15日に作り始めたときにここまでのゲームが完成するとは思わなかった。

毎週末というか毎晩(笑)、大人の工作をしてものすごく楽しかった。

人生50歳を迎えて、こんなものを作れるようになるとは・・・PowerAppsすげー

そして改めて、界隈の方々に感謝申し上げます。

様々な知見を日ごろから発信していただいて本当にありがとうございます。

私は、この程度のスキルですので、真似しかできませんが、組み合わせればこんなことが出来た!!ということで閉めさせていただきます。

 

Special Thanks

ふらりさん

ギークフジワラさん

益森貴士さん

出戻りガツオさん

Akiraさん

おうじゃさん

コルネさん

ヨウセイさん

RezaDorraniさん

本当にありがとうございます。

 

学ぶとは真似ぶから始まる、問合せアプリを作ってみたお話

職場内の問合せってけっこうありますよね

 今回は、色んな機能をパクりまくって問合せアプリを作ってみたお話です。

 みなさんの部署には問合せはたくさん来ますか?ではそれはどんなルートで来ますか?電話?メール?それともチャット?

 ルートが多元化されていればいるほど、その情報管理は面倒になりますよね?もちろん、受け手側の部署も一人ではない場合が多いでしょうし、そうなると受け手側の部署内での情報共有も大変です。

 私の身近な例であった事例だとこんな課題がありました。

1.問合せの来るルートが複数ある

2.それ故、受け手側の回答者に偏りが生じている

3.部署内の情報共有、特に添付ファイルに手間を要する(ダウンロードとか)

 

じゃあどうする?

 ますはルートの一元化です。これはPowerAppsでのアプリ化一択です(笑)、使うデータソースはSharepointリスト、まあここでは件数のことは考慮せずにいきましょう。

たったこれだけです(笑)、いやだって最低限必要な情報ってこれだけですよ。

画面作ってもこんな感じですよね

 次に1件の問合せがどのくらいのラリーで終わるのかに着目します。

よーく考えてみてください、これだいたい2・3回のはずです。5回も10回もラリーするのならば別の打合せするはずです。

 ということは、こんなワザが使えませんかね?

youseibubu.com

 

ハイ、ありがたく実装させていただきました。

この機能は問合せ側だけじゃなく、回答側にも実装すれば、問合せと回答のラリーが可視化されますね。

 

添付ファイルとかダウンロードするの面倒ですよね

 問合せをする側と、回答をする側、この人たち同じファイル見てやりとりしたほうがいいですよね?かつそれもリアルタイムで修正されたらいいですよね。

 そうすれば無駄なダウンロードする必要もないし、かつどんなやりとりしたのかがそのまま残ります。

【めんどくさいを解決】Power Apps の添付ファイルをダウンロードすることなくブラウザ上で閲覧する方法

 ということでこの機能も実装します。

かつ添付ファイルも差替えとか追加したいこともあるでしょうし、チェックボックスで切り替え可能にします。追加したギャラリーのVisibleを切り替えるだけですね。

これにて双方がSharepointリストにある同じファイルを見て、触ることができます。

 

これだけじゃ面白くないなあ・・・と

 これだけだと、ただ単に2つの記事を真似しての足し算でしかありません。ここは少し捻りましょう(笑)

 ということで回答側に回答案生成機能を追加!!

*プレミアムコネクタでOpenAIのAPI叩いてます。

 

うーんなんとも粗雑なレイアウト、まあこの記事向けに突貫工事したのでお許しを

 

回答案生成ボタンには以下を仕込んでいます。


Set(varResponse,ChatGPT.SendUserMessage(Collect(_messages,{role:"user",content:DataCardValueQ_2.Text&"の問い合わせが来ています。回答の案を作成してください。"}),{model:"gpt-3.5-turbo"}));Collect(_messages,First(varResponse.choices).message);Set(popup,true)

 

回答案をポップアップで出してみました。回答案はテキストインプットにしてありますので、修正も可能です。コピーボタンでコピーも可能です。

qiita.com

 

このアプリ、春先に作成したんですが、思い出しながら復習も兼ねて今回再現して、かつ回答生成を追加してみました。けっこう忘れてることありましたねえ(笑)

あとはお好みに応じてフロー追加してTeamsに通知してみたり、メールしてみたり、まあ拡張は無限ですね。

 

さらにBing-Chat使えば

こんな感じでPDF添付されていたとします。

添付ファイルのギャラリーOnSelectには以下を仕込んでありますので
Launch(ThisItem.AbsoluteUri & "?web=1")

クリックしてEdgeで開いて、Bing Chat Enterpriseを使うと・・・

すげえよAI、要約しちゃったよ(笑)

 

ということでポエム第2弾でした。

 

50歳のオジサンがPowerPlatformを​ ホンノ少し使えるようになったお話​

dai365と申します。齢50のオジサンです。

プロではないのでポエムしか書けませんが、そんな私でもホンノ少しPowerPlatformを使えるようになったお話を書かせていただきます。

これから学ぼうとしている方、今手を動かしている方、そんな方の何かの参考になればと思いこの記事をまとめてみました。

*個人の見解が非常に多く含まれます。

話は3年ちょい前にさかのぼります

2020年5月

当時、世はコロナ禍、かくいう私も出勤制限により在宅勤務をしておりました。

実際問題、在宅「勤務」とは言いながら、実は「ヒマ」

何にもすることのない私は、Youtubeを一日中見ていました。

すると目にしたものは・・・

はじめてのPowerAppsここで私は初めてPowerAppsというものがあることを知ります。

https://www.youtube.com/@JapanPowerPlatformUserGroup

それと同時にどうしても触ってみたくなり、365 for businessの契約をします。

ん??お前法人じゃないよね?というツッコミはなしで(笑)

そのくらいどうしても触ってみたかったということでご容赦ください。

 

今にして思えば、無謀・・・

2020年5月~夏くらい?

当時の私のスキルレベルはエクセルのVlookup程度です。

また2009年くらいにアクセスを購入し、何も出来ずにお蔵入りした経験もあります。

そんな私がなぜPowerAppsに惹かれたのか、それは自動化

なにせ手書きと手入力が心の底から嫌い

ましてや誰かが入力したものをもう一度入力するなんて(そんな仕事は猿にでも任せればいい)

アカウント登録して、さあやり始めました・・・・がしかし

はじめてのPowerApps見ながら一生懸命写経したんですよ・・・

なんとなく80%くらいは形になるんですよ・・・

でもね、PowerAutomateとかが出てくるとチンプンカンプンなんですよ

Google(おっと他社)で調べてもなーんにも出て来やしない

今にして思えばそりゃそうですよね、出て間もない製品なのですから

みるみるうちに残骸ばかりが積み上がりました・・・

 

当時を思い出すと

今と比べると何といっても知見がネット上にないんです。

なので初学者はすぐに行き詰ります。

当時Youtubeで配信してたのって吉田大貴さんの他だとマイク根上さんくらいな気がします。

後にマイクさんにもUdemyでお世話になりますが、当時は活舌悪いなあくらいにしか思っていませんでした。

とにもかくにも私の中で一度ここでPowerAppsは一度挫折しています。

ですが、代わりにやっていたのはエクセル新関数とかVBAでした。

そのころの私は田中亨先生の田中メソッドに夢中になっていました。

 

諦めきれなかったんでしょうね、きっと

VBA覚えながらも諦めきれなかったんでしょうね(笑)

この本、たぶん予約してまで買ってますね

で届いて、確か出張に行くJRの車中で読んだ記憶があります。

この本自体は初学者にもわかりやすく

でも時々わからない関数とかたくさん出てきて

まあ、とりあえずアプリはこんなふうに作れるということは理解した・・・ような気がします

ですが、まだ手は動いていない(笑)

 

転機は突然に

2022年3月

職場内の要領を一元化して見やすく探しやすくしよう、というお話です。

これ最初はエクセルにハイパーリンクつけるつもりでした、ホントの話です。

なんですけどフィルター関数の戻り値はテキストです・・・

ここで思い出しました!!PowerAppsもう一度やってみよう!!

ホントに人生何が幸いするかわかったものではありません(笑)

金曜の夜から苦闘です

Sharepointドキュメントライブラリを検索するアプリをなんとか試作

そのときに参考にしたのは

https://www.youtube.com/watch?v=I9TBCwd22m4&t=618s

ギークフジワラさんのこの動画でしたね

この動画があったからこそ最初のアプリでいきなりSearch関数とか使っています

大変申し訳ないですが、Learn全く見ていません・・・

 

まだまだ少ない情報を漁るように

2022年5月

Search関数とLaunch関数くらいしか使っていない要領検索アプリを無事リリースさせた私は、次なるアプリを作ってみたくなります。

ですが、ここからが苦難の道のりでした。なにせ体系だった知識がどこにもない(ように見えた)

とにかくGoogle(すいません他社で)で検索し、出てきた記事で読めそうなもの、理解できそうなものをやってみて、その積み重ねでどうにかこうにか次のアプリの試作をします。

当時だと高田弘介さんのこれとか見てたように思います

また、1つアプリを完成させたので、改めて吉田大貴さんの動画も見返してました。


https://www.youtube.com/@user-et9ho4eh4p

 

いやあ、見返して赤面です()

FacebookにJapan Power Apps User Groupというコミュニティがあります。

私、これに入ったの2022年だと思っていたんですが、どうやら2020年なんですね・・・

最初の質問がこちら

しかも回答していただいているのが山田晃央さんですね

まったくもってお恥ずかしい・・・ワラをもつかむ思いだったんでしょうね

 

ここでとある人に出会います

くだんの要領検索アプリを作り始めたころから、またしょうもない質問を再開します。

そんなときにいつも丁寧にわかりやすく回答をしてくださる方に出会います。

それもわかるまで教えてくれます。

こんなアイコンの方で、最初はどこのオジサンかと思ってました(笑)

 

まだこの時点でも見様見真似

2022年11月

見よう見まねでいくつかアプリを完成させた私も、ここで行き詰ります

車両運転日報アプリを作成していた私は、こんな壁にぶち当たります

Sharepointリストって5000件以上格納できないの?

それやるにはDataverse for Teamsで作るしかないの?

アドバイスのとおりその環境で作り直したんだけど、ちょいちょい落ちる・・・

Youtubeの動画に色々便利とか載ってるけど、よーわからん

ここで私はひとつの思い付きをします

あのFacebookで助けてくれた方に仕事としてでいいので教えてほしい!!

ということでN社にメール!!

www.nsurf.co.jp

そうすると同社の社長から返信が!!

 

ここで同社から提案が

2022年11月

同社から提案されたのは

目指すものは〇〇さんが市民開発者となる姿で間違いないですね? ハイ、そうです

であれば、かくかくしかじかでお手伝いさせていただきます

ということで技術指導がスタートしました。

ここでは、私の作成したアプリを同社で再現いただき

さまざまな多岐に渡る技術指導をいただきました。

このおかげで、同アプリはSharepointリストでも問題なく動作する仕様となり

また、試験稼働に向けた不安も払しょくされました。

 

この時期に私は基礎を固めます

2022年12月

ここまでの見よう見まねで基礎が固まっていなかった私は以下のことで基礎を固めることができました。

マイク根上さんのUdemy初級編

これで関数全般の知識を身につけます

https://www.udemy.com/course/powerapps-c/

 

Akiraさんのyoutube、PowerPlatform学習アプリ作成動画

関数全般もさることながら、テクニック満載です。

https://www.youtube.com/@Akira-bb5sg/videos

 

そして配列の苦手だった私はこんな動画の写経も

https://www.youtube.com/watch?v=NepvIvoaf9U&t=4s

ここで一気に関数知識を広げることができました。

 

そして私は専任になる・・・

2023年2月

別の部署に異動した私は、技師という肩書となる。

内心「いやー技術なんて知らないし・・・どうすんの、これ」と思いながら

ここで私はConnpassというコミュニティサイトの存在を知ります

なんかよくわからんし、場違いかもしれないけど、無料なら参加してみよう

ということで参加してみました

正直、素人にとってはドキドキもんでしたけど、コミュニティの内容に感動

気ままに勉強会

2023年2月から気ままに勉強会に参加しています。

PowerAutomateの知識がへっぽこでしたので

このコミュニティに参加して、最初はちんぷんかんぷんでした

ですが、毎回参加しているとほんの少しづつですがわかりみが増えてきました

最初のころはJSONって?何それ?って思っていたはずなのに

今ではJSONで取得できるならitem関数で取れちゃうよね、みたいな感覚です

主催されている方々の労力は大変なものがあると思いますが、本当にこのような場に感謝です。

 

JPPGB

コルネさんが主催しているこのコミュニティ

PowerAppsでゲームを作るという個性的なものですが

初めて参加した#4が衝撃でした!!

名だたる方々がNO9のゲームを作り、それをネタに登壇するというものでした。

凄腕の方でもゲーム作成、ロジックのアプローチが異なり

見ているだけで面白くて面白くて

ついでに見ながら自分も手を動かしてみたら「あ、出来た」となり

この回は私の中では神回となっています。

https://jppgb.connpass.com/event/273912/

 

DTS登壇!?

昨年の年末だったと記憶しています。

MS社からDTSに登壇してみませんかと打診を受け

もの好きで目立ちたがりの私はやってみたいなあと思いながらも恐る恐る上司に報告(笑)

その後、2月登壇が4月に延び

私は技術もない技師となり、技術身につけるためにConnpassとか知らない世界に踏み出し

さらにそんな私に追い打ちをかけたのは

え?登壇って2社なの?しかもP社!!!

えええええええーって気持ちでした

だって一介の50のオジサンですよ(笑)、本職相手に何話せって言うんですか

それからというもの

2023年3月

もう1社がP社と聞いてから

それとなにせ技術のない技師!!しかも4月からは「主任技師」などと昇格します

このころはとにかくQiitaの記事見て写経してた気がします

益森さんの記事見ながらOpenAIのAPI叩いてみたり

毎週金曜日は、Akiraさんとやまさんの

https://appsweeklynews.connpass.com/

毎週土曜日は、気ままに勉強会

https://kimamani.connpass.com/

内容わからんくてもとにかく見る、聞く、参加する

(晩酌しながらなのでたまに寝落ちしている)

 

新年度になって

2023年4月

専任になって自分の職場にこの知識を広めるためにはどうすればいいのかを考えました

ここまで書いたように、私は当初情報の少なさに悩まされました

また、聞く人がいないという悩みを抱えていました

だったら、自分が出来る範囲でいいからそれをやれば

私の後からやってみたい人のためになるかもしれない

幸いにして(笑)、私は収集癖の持ち主(プロレス動画2,800本持ってます)

ということで

TeamsにPowerPlatform研究所チームを開設(現在100名強います)

タブにアプリの実装テクニックといえるほどのものではないが記載

タブにようさんの見様見真似で関数アプリ搭載

ここまで見かけて役に立った方のXアカウントとかも全部掲載

で私目線で役に立つ情報をここで発信し始める

気ままに勉強会やコミュニティの資料はありがたくここに格納しています。

 

物まね芸人?

2023年5月

5月の連休過ぎに前述したヨウセイさんとリアルで会います

会食してなんだか楽しくなって、意気投合

で何を思ったのか私はJPPGB#6に登壇します

https://jppgb.connpass.com/event/284143/

内容は実にヘッポコです。ビンゴボードと連動したビンゴカードのアプリです

まあ、このころはそれで精一杯

また、youtube見ながら写経という名の物まねを繰り返します

ギークフジワラさんのこのアプリ、AzureOpenAI必要なんですけど、作ったんですねえ(笑)

https://www.youtube.com/watch?v=jERrUWTm7nA

Akiraさんのこのアプリ、ライブしてたから思わず・・・

https://www.youtube.com/watch?v=5vEkFcDWZRE&t=2192s

 

さらなる衝撃!!

2023年7月

JPPGBゲームコンテスト#0というイベントが開催されます

https://jppgb.connpass.com/event/282845/

改めてプロの技術のすさまじさに触れ、さらに大賞を受賞したヨウセイさんのパワスロに夢中になります。

で、自分でも何か作ってみたくなります

7月15日の夜から作成開始します

そしてヨウセイさんに誘われ「おうじゃさんといっしょ」というコミュニティに足を踏み入れます

https://oujasan-to-issho.connpass.com/event/290808/

もっともっと知りたいという欲にかられ

そこから毎週のように(場違い?ですが)参加し続けます

 

インプットしたならアウトプット

2023年9月

プロレスゲームの作成と同時に、職場では4月来毎月2回の勉強会です。

正直相当ハードです(笑)

苦手なPowerQueryや、他のツールのお悩みもガンガン来ます

講師は私一人です(笑)

Xでもくだいさんが勉強会の勉強会をしますけど、誰かネタありますか?という言葉に反応し、365勉強会でLTさせていただきました

https://jpo365ug.connpass.com/event/290695/

いやーついこの間まで何にも知らなかったオジサンが場違いにもほどがある(笑)

で9月9日には、念願のプロレスゲームで登壇!!

https://jppgb.connpass.com/event/292259/

 

何がポイントなのか?

当初はMicrosoft365、いわゆるExcel、Word、Teamsの知識から入った気がする

なんですが、365の最大のメリットはクラウドツールという点

それとそれぞれのツールがシームレスに連携するという点

ということからすると、PowerPlatform系は避けて通れない

最近は情報も3年前から比べると相当増えてきた・・・んだけど

きっと意識しなきゃいけないのはそれぞれの導入されている環境の差異じゃないかと・・・

私がやっているのはあくまでライセンス内の話、それ以上でもそれ以下でもない

ただしライセンスの範疇がどこまでなのかを知る必要はある

界隈のプロは過去からの知識と経験に基づいて歴史を知りつつやっている

機能も変わり続けるので、過去に遡及してまで覚える気はないけれども

日々、情報をインプットし続けて、アウトプットし続ける、そして続けることが重要

個人的には他のツールではプロレスゲームは作れないのでPower最高です!

 

・・・ってこれAutomateのショバじゃね・・・

わからなかったことがわかるようになってきたお話

 このお話はつい数か月前(3月)にはチンプンカンプンだったことが少しづつ理解できてきて、さらには破壊力満点の生成AIの力でさらに理解するに至ったというお話です。今から何かを始めてみようという方の参考になればと思い、ポエム化した次第です。

 

話の始まりは今年の春先

 とあるアプリを作成していた私はこんな要望を耳にします。

「この入力欄、うちの課員だけ選択できるようにしたいんだよね」と

 当然ですが、当時の私にはそれを具現化する力量などありません(笑)

(まあ、今でもそんなにないのですがね)

 とある方に相談したところこんなお返事が

 

当時の私にはチンプンカンプン

1.起動時処理で自分の部署をフローに送って起動

2.参考のようにユーザーをすべて取る(上限をアップしておく)

3.とった結果からフィルターアクションで自分の部署のレコードのみにフィルター

4.それをアプリに返却する ※文字列で

5.アプリ側でJSONParse関数で結果をコレクションにする。

6.これをプルダウンに指定しておく。 

※ここでSPOのUser列使っている場合などは型の調整も必要

→JSONParse関数や型調整ががちょっと難しめの実装となりますが、Automateの処理をうまく使えばできなくはなさそうです。ご参考までに。

 

なんですがなんとか作ってはみました

これはどうにかこうにか出来たんですよ。

ただ実装はしませんでした。

フロー完了するのに数秒かかるのがどうしても我慢できないので、やめました(笑)

このころの私の知識なんて、アプリに戻したのをどうすればいいのかすらなーんにも理解していませんでした。

 

諸事情によりモザイクかけてますが、ちゃんと取れてます(笑)

ボタンには

ClearCollect(Jcol,全アカウントから部署単位で抽出フロー.Run(Office365ユーザー.MyProfileV2().department))

ギャラリーには

Table(ParseJSON(First(Jcol).json))

jsonってのでアプリに戻してます(笑)

当時はわけもわからず見様見真似してましたね

このときもそれなりに頑張ってはいたんですよ

ForAll(Table(ParseJSON(First(Jcol).json)),Collect(MyDepartment, {name: Text(Value.name)}))

こんなの書いてドロップダウンにしてましたね。

 

で時は流れ12月

今更ながら、なんか以前あんなのやったよなあ・・・あの記事って難しかったよなあ英語だったし・・と

あ!!Copilot!!

と思い付き、Edgeで開いて要約!! あらまあなんと素敵なことでしょう

元ページはこちら

https://powerusers.microsoft.com/t5/Building-Power-Apps/Get-the-list-of-all-Office-365-Departments-amp-Countries/m-p/1580321/highlight/true#M405678

 

あ、これいいじゃん

迷わず即パクリ(笑)

いやーいいですねえAIって

私はもともとが非IT職です。なので専門的な知識では正直かないません。​

​ですがそんな私でも「真似」したり「集めたり」することはできます。​

​現在の世の中は、youtubeやネット・SNSで情報を容易に入手することができます。

ここにAIが加わりました!!​

​そんな時代の利点を生かして、少しでもデジタル化を進めていければと思います。

ないものは作ればいい、日程調整アプリを改造したお話

アドベントカレンダー初参戦です。

はじめましてdai365と申します。

素人がこんな記事書いていいものかわかりませんが、齢50になるオジサンです。

気が付いたらPowerPlatformの魅力にとりつかれておりまして、何故かこんな記事を書いています。

 

せっかくなので12月に限り何本か記事を書かせていただきたいと思います。

内容はこの1年にやってみたことかなと・・・

くれぐれも言ってきますが、素人なので技術的なことはヘッポコです(笑)

 

日程調整アプリは便利だぞ

今年の春先に某MS社から日程調整アプリをいただく機会に恵まれました。

このアプリ、期間と会議時間、会議の参加予定者を選んでボタンを押すと会議の候補を出してくれると言う優れものです。

ちなみに元々はこの記事と同じ機能です。
https://qiita.com/Takashi_Masumori/items/bc3c4588a18ad852a246

いや、別にそのままでも十分に便利になるんですよ、これは

 

なんですが、心の中の私が叫びます(笑)。

これ、このままリリースしたら確実に「会議室の空きがわかる機能ないの?」と言われることは必然でした。

 

とはいえこの当時の私はズブの素人(今でもただのポエマーですが)、そんな改造ホントに出来るんかいって感じでやってみたお話です。

 

まずは検索ボタンで何をやっているのかの確認をしてみました。

ClearCollect(colMeetingTimes,AddColumns(Office365Outlook.FindMeetingTimesV2({RequiredAttendees: Concat(colAttendees,userPrincipalName & ";"),

MeetingDuration: cmbDuration.Selected.Minutes,

Start: Text(DateTimeValue(dteStart.SelectedDate & " " & drpStartTime.Selected.Value), DateTimeFormat.UTC),

End: Text(DateTimeValue(dteEnd.SelectedDate & " " & drpEndTime.Selected.Value), DateTimeFormat.UTC),

MaxCandidates: 20,

IsOrganizerOptional: false,

ActivityDomain: "work",

MinimumAttendeePercentage: 10}

).meetingTimeSuggestions,

"StartTime", // Convert return from UTC to local time.

DateAdd(

DateTimeValue(meetingTimeSlot.start.dateTime),

-TimeZoneOffset(),

TimeUnit.Minutes),

"EndTime", // Convert return from UTC to local time.

DateAdd(

DateTimeValue(meetingTimeSlot.end.dateTime),

-TimeZoneOffset(),

TimeUnit.Minutes)));

 

今でこそ、これスラスラ読めるんですが、当時は七転八倒でしたね(笑)一個づつ解読ですよ。今ならChat-GPTに放り込めばOKだとわかるんですけどね、どんだけトホホだったんだか。



つまり、これはOffice365Outlook.FindMeetingTimesV2という関数で、スケジュールの調整をするということをやっています。

で、その結果をcolMeetingTimesというコレクションに格納しています。

 

思えばこのときほぼ初めてに等しいくらいLearnをマジマジと読んだ記憶があります。

 

で、ですね、じゃあ会議室どうする?

最初に思いつくのは会議室も会議参加予定者に入れちゃう?ってのなんですが、これには欠点があります。

それは会議室が空いていなくても例えば4人+会議室で会議室だけ空いていなくても80%とかって候補が出てきます。嫌ですよね、これ。

 

ってことで何をしたかというと

会議室だけ別コレクションを作ることにしました。これはさっきの応用で簡単にできます。

ClearCollect(colMeetingTimes3,AddColumns(

Office365Outlook.FindMeetingTimesV2({RequiredAttendees: Concat(

colAttendees3,userPrincipalName & ";"),

MeetingDuration: cmbDuration.Selected.Minutes,

Start: Text(DateTimeValue(dteStart.SelectedDate & " " & drpStartTime.Selected.Value), DateTimeFormat.UTC),

End: Text(DateTimeValue(dteEnd.SelectedDate & " " & drpEndTime.Selected.Value), DateTimeFormat.UTC),

MaxCandidates: 200,

IsOrganizerOptional: false,

ActivityDomain: "Unrestricted",

MinimumAttendeePercentage: 100}

).meetingTimeSuggestions,

"StartTime", // Convert return from UTC to local time.

DateAdd(

DateTimeValue(meetingTimeSlot.start.dateTime),

-TimeZoneOffset(),

TimeUnit.Minutes),

"EndTime", // Convert return from UTC to local time.

DateAdd(DateTimeValue(meetingTimeSlot.end.dateTime),

-TimeZoneOffset(),TimeUnit.Minutes)));

 

ここでのポイント?は3つ

MaxCandidates: 200,

これは候補の数を人同士が調整した候補よりも確実に上回るように200にしています。

200の根拠は適当です(笑)

 

ActivityDomain: "Unrestricted",

これは活動内容の制限を外しています、これにより会議室だけは業務時間外であっても候補が示されます。

 

MinimumAttendeePercentage: 100

ここは当然のことですが、会議室の空きを調べたいので100ですね。

 

でここからはある意味エクセルチックな解決方法です。

会議参加予定者の会議候補として示された日時の候補が会議室の会議候補にあれば会議室は空いています。なければ会議室は空いていません。要はふたつのコレクションを比較するってことです。

 

なんとも駐車場の満車表示みたいですね(笑)

 

この改造をしたの今年の4月なんですが、本当に良い経験になりました。

ということでポエム第1弾終了です。