開いたExcelの中身を取り込む
先日の続きで、実際に開いたExcelテンプレートに入力されたデータをWebで取り込む処理を考えていた。最初は、「Import」ボタンを押したら、1)Excelファイルを保存2)FileUploadコントロールを使ってサーバに送る3)SPをコールして、中でOpenRowSet+Jetでデータを読み出し、チェックを掛け、結果を返す4)結果をGridViewで画面に表示するというようなものをイメージしていたが、テンプレートでレイアウトは決まっているから、テキストに吐き出してそれを送り、BULK INSERTでデータを読み出した方がいいかな、と思いなおす。実際に試してみると、OnClientClickでVBScriptでローカルにCSVは簡単につくれたが、そのパスを画面上のFileUploadコントロールにセットすることができない。FileUploadコントロールにはそのようなプロパティがないし、JavaScriptでセットしようとしても、反映してくれない。セキュリティ上シームレスにファイルをセットして送ることはできないのかもしれない。或いは技術がないだけか。とりあえず、できなかったので、ファイルはやめにして、文字列に組み上げたものをHiddenFieldにセットして、それをPOSTするアプローチに変更する。VBScriptで組み上げた文字列をJavaScriptをコールする形で書いてみると、やはりセットできない。しからば、と、VBScript側をFunctionにして、var s; s=GetExcelData(); ContentPlaceHolder$hdnData.value=s;とやってみたら、何とかうまくいった。送った文字列は「a!b!d!c!e,g!h!i!j!k,l!m!n!o!p,..」という感じで、区切り文字と行区切り文字を分けておくので、DECLARE D_CUR CURSOR FOR SELECT SEQ, ITEM FROM VARTOTBL(@STR)OPEN D_CURFETCH NEXT FROM D_CUR INTO @LINEWHILE (@@FETCH_STATUS=0)BEGIN SET @LINE=REPLACE(@LINE,'!',',') INSERT INTO @TABLE SELECT MAX(CASE WHEN SEQ=1 THEN ITEM END), MAX(CASE WHEN SEQ=2 THEN ITEM END), .... MAX(CASE WHEN SEQ=x THEN ITEM END) FROM VARTOTBL(@LINE) FETCH NEXT FROM D_CUR INTO @LINEENDCLOSE D_CURDEALLOCATE D_CURといったノリでテーブルに復元し、必要なチェックを掛ける。そうして送る仕組みは何とかできたが、やはりポイントは「Excelに入力する」というのは本当にユーザは便利だと思うか、というところになる。Web入力では「複数行まとめて入力したい」「上のデータを必要なだけコピーして入力データを作りたい」「別のところからまとめてコピー&ペーストしたい」などのAccessユーザニーズにはほとんど対抗できない。それがExcel入力を代替案として考えた理由だが、入力セルにリストボックスを仕込もうとするとExcelは非常に制約が多くてどうやっても使いやすくはならない。1時間ほど考えて導き出した結論は、「ダブルクリックでリストを表示させるしかない」。Excelにマクロを仕込むのだけは避けたかったが、これ以上に許容されそうな入力インターフェースが思いつかなかった。まあ、割り切って実装してしまえば、まあ、これでいいかなという気にはなってきたけど。