2013年10月22日火曜日

[備忘録的] 仕事の話

たまには仕事の話も書こうと思います。


ちょっと(半)農blogになりつつありますが、元の元は日記的なblogで、もうちょっと自分の記録を残しておくべく。
と言うか、仕事の話、ずっとサポート関係の仕事をやっててしかもコールセンターじゃないので、文章にするのが難しかったのもあったのでなかなか書けないでいたとでも言うか。

今の仕事は、何か巡りめぐって元の元(?)に戻ったと言うか、ちょっとした開発をやっています。しかもAccessで。経緯的な部分とかその辺の話はまた書くとして、ちょっと備忘録的にたまにAccessネタを書くことにします。自分のために、です。

派遣で仕事してるのもあり、やった仕事をあまり持ち出せないと言うこともあって、次のところに行くと躓いた所や小ネタを又同じように探す、なんてことをしてるので、それを防ぐために。なので、細かいコードとかは書けないと思うけども…。

ちなみに今の仕事では、マクロは一切使わずに全部VBAで一から書いています。

■当たり前の所の話
バリバリやってる人には当然の事ながら、今回じっくり腰を据えてやるようになってようやっと分かったのが、レコードセットの部分。

当然ながらテーブル構造を考えて、フォーム・クエリを作っていて、レコードがどうやって保存されるかって言う部分について、前まではすごく何となく作ってしまっていたと言う感じでした。(ちなみにAccess+VBAでの開発は3度目で、前回は超内輪向けながら初めてVBAで全部作ったのだけど、その時が何となく、でした)

今回、あれよあれよと言う間に作るものが結構盛りだくさんになりつつあるのと、一応メインが開発なのでじっくりとやることになって、先々まで使えることを考えたこともあり、「テーブルを年度で自動で分割してそれをテーブルリンクを再度組み直して古いテーブルから新しいテーブルまでを全部見ながら一覧やら新規登録やら修正やらが出来るように…」と言うことをやるにあたって、レコードセットが分からないとどうにもならず、結構色んなブログやらMSDNやらも読みました。(ちなみに書籍は一切読まず。実際のコードの方が役に立つと思っているため)

でもそれが分かるようになったら、随分と楽になりました。
ただ次に書くことで結構つまづきましたけど…

■添付型フィールドの話

今はAccessの2010(Win7で)でやってます。
部署の他の人は皆まだXP+Access2003なのに(他の部署には何故か97も…)、最近入ったためかWin7+Access2010と言う環境でした。

それにプラスして作ろうとしているシステムでは、添付ファイルをつけると言うのが命題にもなっていて、どうしてもAccess2007以上じゃないとダメと言うことが分かり(2003ではその機能が使えない)、一番目新しいものがこの添付型フィールドの扱いでした。

作り始めてレコードセットがようやっと身について(思い出して?)来た頃、最初はフォームにレコードセットを1つのテーブルでセットして、あのコントロールが出る添付型フィールドはフィールドをペッと貼り付けてレコード保存させればOKだったのです。

ですが、色々作り始めて仕様も色々変わって、1つのレコードに1つの添付ファイルしか付けられない部分が出てきてしまい、そうすると添付型フィールドのコントロールを貼り付けるのではなく、1つしか添付出来ない方がいいかな?と思って(判定するって手もあったのですけども)それをやり始めたら、あの「複数型フィールドを持つ」と言う特性がなかなか理解出来なくて苦労しました。

また一番苦労と言うか「何故?!」としばらく時間がかかってしまたのが「削除」。
添付を貼り付ける際にはコントロールは使わずに、コマンドボタン→ファイル選択のダイアログ→ファイル選択→アップロードでアップロードは出来たのですが、そのファイルを変更出来ない…。「重複」と言うエラー。ならば、「削除して再度貼り付ければいいか」とやっても同じエラー。

うーんと唸りつつ、とりあえずステップでイミディエイトに添付型フィールドのFileNameの値を表示させてみたら、あらま、そういうこと?みたいな感じでした。
1度ファイルを貼り付けた後に削除する場合には、その添付型フィールドの値を「全部」削除しないとダメなのでした。(と言うか、私はテストで何度も同じテスト用のファイルを使いまわしていたのです)

参考になったページはこちら:
http://homepage1.nifty.com/tsware/tips/tips_491.htm
上記の参考ページのコードにあるように、添付型フィールドをレコードセットとしてセットしてから、.EOFまでLOOPで回しますが、「ファイル名が入っていたら削除」と言うのをやって初めてクリアされる、と言う形です。

ちなみに参考ページのコードにあるように「指定したファイル」で削除しても、その指定したファイル自体は削除されますが、もし他に過去にアップロードしたファイルがあった場合には残ってしまうので、同じファイル名で再度アップロードしようとした場合にはエラーになってしまいます。(それが私ははまった所でした)
なので、固定のファイル名ではなく「FileNameに入っていたら削除(でLOOPで全部回す)」と言う組み方をした方が無難な気がしました。(その後のキー重複エラー防止のためにも)

あとこの件で苦労した理由が、この添付型フィールドについてググっても、あんまりネットでコードや情報を公開している人が少ないようです。あまり使われていないのでしょうかね。(まぁ単にコントロールを貼り付ければ終わりではありますけどね…。)
もう何度も手書きで「これをレコードセットして、添付型フィールドをセットして…」と机上デバッグをやりました。

■クエリの外部結合

クエリは当然ながらよく使いますし、2つのテーブルを結合してクエリをかけると言うことなどは普通にやってました。

ただ今回はまったのが、Aと言うテーブルとBと言うテーブルを結合させて(リレーションは張ってはいます)、ある条件のものをAから抽出してリスト表示させるものだったのですが、Bと言うテーブルにレコードがないものを表示させることでした。
普通に結合してはダメで、外部結合すればレコードがないBのテーブルの情報も「無い情報」として表示させることが出来ることは分かったのですが、そこからがまたネックでした。

AテーブルのindexAと同じ値を持つBテーブルのindexBは複数あるのですが、その1つのindexAに対する複数のindexB × 複数のうち、一番最後のレコードのみ表示させると言うものです。

<Aテーブル>
indexA
--------
1
2
3
4


<Bテーブル> *indexB0がAテーブルとのリンク部分
indexB0 indexB
1 1
1 2 ←
2   ←
3 1
3 2
3 3 ←
4 1 ←
5   ←


Aの数字+Bの←の部分のみが取り出したい部分です。
(実際にはもうちょっと条件がありますが、とりあえず)

単純にLEFT(場合によってはRIGHT) JOINするだけではダメで、集計クエリにし「indexAをグループ化」して「indexBの最後」とする必要がありました。(これはデザインモードでのやり方なので実際にはLast(なんとか)と言う形+Group BYを全部のフィールドに)

私が悩んだのは全部のフィールドでグループ化するのか、と言う点でした。
ちょっと上で書いた例ではフィールドが少ないので(例がよくない)あれですが、単に表示させたいだけなのでフィールドそれぞれ全部にグループ化するのか、と言うところが浮かばなかったのでした。集計クエリにすると、集計をしないフィールドが1つでもあるとエラーになってしまうので、「じゃあ何の集計すればいいのよ~」と何度も心の中でつぶやきました。無意味に演算してみたりとか…。

***
もっとバリバリやってる方には当たり前の話なんですが、とりあえず自分用なのでお許しを。