お仕事の最近のブログ記事

今回の東京出張は、大変セブン−イレブンにお世話になりました(笑)

金曜日の夜にお客さんに FAX する予定だった見積書のことを、東京に移動中の新幹線の中で思い出した(^^;
金曜日の夜は別のお客さんと飲んだのだが、お客さんとの待ち合わせ前に一人で二軒ハシゴ。その後お客さんと三軒ハシゴという幸せな時を過ごしたせいで完全に忘れていた。

月曜日に緊急で行う作業に関する見積もりで、それを確認してもらってすぐに注文書をもらわないといけない。
メールで送ればいいじゃん?いや、そのメールも含めたネットワークが一切使えないトラブルの緊急対応なのだよ(笑)

20180217_seven.JPG
一応、MacBook は持っていたので、OpenOffice.org で見積書、注文書、FAX 送信票作成。PDFにして、新幹線の中からセブン−イレブンのネットプリントサービスに送信。
東京に着き、馬喰町の駅を出たらすぐにセブン−イレブンを探し、まずは印刷。さらにそれを FAX 送信サービスを利用してお客さんにお送りした。
ほどなく、我が家の FAX にお客さんからの注文書が届いたと嫁さんから連絡があった。セブン−イレブンよ、ありがとう。

それともうひとつがお金の話。
持っていくはずだった現金を書斎の机に忘れてきて、財布の中にはそのへんの高校生より少ないであろう 4千円しか入っていない。

まあ、ホテル代はカードで精算するつもりだったからいいけど、「メシ代を節約しなきゃ。ホテルで朝飯はただで食えるし、日曜日の昼飯は多分提供されると思うから、土曜、日曜の晩飯だけなんとかすればいいか。お土産を買う金はないが、そこは後日別のこと(外食とか)で嫁と子供には許してもらおう」・・・とか思っていたのだが、移動中に昔の仕事仲間と夜飲もうってことになって・・・(^^;
いや、正確に経緯を書くと、飲みに行こうって約束をしたときに「あれ?そういえば」と金のことを思い出した(^^;

・・・が、楽天銀行にチケット購入料金などでいくらかお金を入れていたことを思い出し、セブン銀行 ATM で引き出し事なきを得たのであった。ちなみに日頃楽天銀行のカードに ATM で金の出し入れをすることがないので、暗証番号はうろ覚え。しかし、奇跡的に正解したのである(笑)

ということで随分とセブン−イレブンにお世話になり、「便利な世の中になったなあ」と思う反面、お客さんから「色々方法はあるんだから今すぐなんとかしろ」なんて言われるケースも増えていくことだろうなぁ・・・と(^^; 世知辛い世の中だ。

テクノロジーの発達は決して人を幸福にするばかりではないのである。
Arduino UNO を基盤に作成したシステムでイノシシ用の箱罠の制御をしたくてあれこれしているんだけど、とりあえず概要としては、

・モーションセンサーで箱罠にイノシシ(何らかの動物)が入ったのを検知
・モーションセンサーを OFF にして、測距センサーを ON
・測距センサーから 60cm の位置(地上から 40cm)に物体を検知したら測距センサー OFF
・モーターを 1秒間回し、罠の扉を閉めるトリガーのワイヤーを引く

という動きをさせたい。
まあ、これだと無限ループに入る可能性があるから、何十秒か測距センサーを稼働させ検知出来なければ、一旦モーションセンサーの監視処理に戻す等の細かい制御は必要なんだけど。

ちなみに、モーションセンサーだけで罠に動物が入ったのはわかるんだから扉閉めればいいでしょ?って考え方もあるだろうが、それだとうり坊とか狐、たぬきなどの小動物でも扉が閉まっちゃうから。
なので、測距センサーで体高を計って、40cm以上の高さがある時だけ扉を閉めるんやね。

じゃあ、モーションセンサーいらんやん。測距だけでええやんって話だけど、測距センサーって無茶電気食うのよ。なので、通常はモーションセンサーで監視をし、何かいれば(モーションセンサーに検知されれば)測距センサーの監視に切り替えるわけ。

ということで、昨夜、こんな仕組みを作ってみた。

20171101_arduino1.JPG

回路図が書けないので、実際の接続図ね。
モーターはまだ接続していない。12V のギヤードモーターって、必要な電流量が 500mA とかなんで、直接 Arduino に接続しても回らんのよ(^^; Arduino からの出力が 20mA なんで、全然足らん(^^;
トランジスタとか使って、高い電流が流れる回路を作ってやらないといけないので、とりあえず昨夜はモーターを動かす代わりに LED を点灯させてみた。

プログラムはこんな感じ。

int sn = 0;
void setup() {
 
     pinMode(8, OUTPUT);      // デジタルピン 8番から測距センサーに 5V 供給
     pinMode(7, OUTPUT);      // デジタルピン 7番からモーションセンサーに 5V 供給
     pinMode(4, OUTPUT);      // デジタルピン 4番からDCモーターに 5V 供給(実際は LED)
     pinMode(2, INPUT);       // デジタルピン 2番にモーションセンサーの検知結果を入力
     Serial.begin(9600) ;     // 9600bpsでシリアル通信のポートを開きます
     digitalWrite(7, HIGH);   // まずは、モーションセンサーを ON
}
void loop() {
     // モーションセンサーのチェック
     if (sn == 0) {
        // 2番ピンを確認(検知情報)
        if (digitalRead(2) == HIGH) {     // 動体検知された!!(2番ピンが HIGH(検知!!))
          sn = 1;  // 次の処理に移行するため、1をセット
          digitalWrite(7, LOW);  // モーションセンサー OFF
          digitalWrite(8, HIGH); // 測距センサーを ON
        }
     }
     // 測距センサーのチェック
     if (sn == 1) {
       int ans ;
       ans = analogRead(0)  ;   // センサーから読込む
 
       // 60cm より近くなったらモーターを 5秒回す
       if (ans >= 110) {
          sn = 2;  // もう何もしない
          digitalWrite(8, LOW); // 測距センサーを OFF
          digitalWrite(4, HIGH);   // モーター ON
          delay(1000) ;            // 1000ms(1秒)時間待ち
          digitalWrite(4, LOW);    // モーター OFF
       }
       
       // 測距は 3秒ごとに行う      
       delay(3000) ;            // 3000ms(3秒)時間待ち
     
     }
}

で、実際に動かしてみたら・・・

20171101_arduino2.JPG

おお、ちゃんと動いたよ。
最終的に、センサーから 60cm以内のところに手をかざすと LED が点灯。

なんで、60cm = 110 なのかは、「赤外線測距センサー(GP2Y0A21YK)を Arduino で試す」あたりを見てちょ。

これで、あとは、

・モーター用の回路を作って LED と交換
・6V 電源(単3電池 x 4)で動くことの確認
・とりあえず、実地テストのためのケース等の作成(モーターにつけるプーリー等も)

ってあたりが残作業。最後のケース作りとかが一番手間がかかりそうやなあ・・・


以前、「赤外線測距センサーを注文し直し(^^;」というエントリーで書いたように、最初に購入した測距センサーでは測距出来る距離が考えている要件に足りなかったので、別のセンサーを改めて購入し直した。

その部品が先週届いたのだが、今日になって、やっと Arduino につないでみることが出来た。測距センサーは SHARP GP2Y0A21YK。測距範囲が 10~80cm のやつ。

接続図(回路図に非ず(^^; 回路図、よくわかんねえ(^^;)はこんな感じ。

20171029_arduino1.JPG

「小さな電源の場合は、電源ピン付近に10uF程度のコンデンサを入れた方が安心」という記事を見たので、「赤外線測距モジュールで物体の距離を測ってみます(1/2)」というページを参考にコンデンサも入れてみた。

んで、センサーから目標物の距離によって、Vo コネクタから出力される電圧が変化するので、それを Arduino のアナログ入力ピンで拾うんだけど、数値はボルト数ではない。
アナログ入力ピンから読んだ値 ÷ 1023 × 5 でボルト数になるみたいだけど、わざわざボルトに直して値の評価をする必要もないし、そもそも、どうも電圧にも個体差があるようだ。

ということで、こういうプログラムを作って、距離によって実際の値がどのように変化するか調べてみた。

/*
 * GP2Y0A21 sensor tester
 */

void setup() {
     pinMode(8, OUTPUT);      // デジタルピン 8番から 5V 供給
     Serial.begin(9600) ;     // 9600bpsでシリアル通信のポートを開きます
     digitalWrite(8, HIGH);   // 電源ON
}
void loop() {
     int ans ;

     ans = analogRead(0)  ;   // センサーから読込む
     Serial.println(ans) ;    // シリアルモニターに表示させる
     delay(5000) ;            // 5000ms(5秒)時間待ち
}

実際にアナログピンで取れた数値はこんな感じ。

10cm
480
477
479

20171029_arduino2.JPG
20cm
271
271
272

30cm
202
204
203

40cm
185
185
186

50cm
176
177
178

60cm
110
110
110

70cm
105
106
106

80cm
96
106
102

目標物を手持ちで計ったんで、若干バラつきがあるけど、まあ、だいたいまとまった数字が出てるね。
数値と距離の関係を XY グラフにした時、線は直線ではなく二次曲線「みたい」に曲がる。だから 10~20cmでは数値が大きく変化するが、70~80cmではあまり変わらない。
この曲線を完璧に計算式で再現するのは相当難しいらしい。それもあって、やはりこのように実際の数字を計ってみるのが一番良いようだ。
Facebook フレンドが「音声で命令するTV」のことが出てくる記事をシェアされてて、そのこととはちょっとずれるんだけど、「人前での音声操作」を「抵抗感があるヤツは古いヤツ」みたいに言う人、つまり自分の「オピニオンリーダー」気質の異常性を忘れている人に意見しとこう(笑)

Google Glass の話の時にもあったが、例えば俺が「街なかで音声でメガネに命令とか出来るかよ、恥ずかしい」とか言ったら「それは感覚が古い。」とか言うヤツがいたわけよ。

いやいやいや、それ「恥ずかしいと思わないお前の方が異常だから」と教えてあげるんだけど、聴く耳持ってくれんね(笑)

オピニオンリーダー、あるいはアーリーマジョリティの感覚を「普通」みたいに言われるとねえ・・・(^^;
例えば目の不自由な人が Google Glass に音声で指示をしていれば、それは「不自然だけど許容しなくてはいけない」事柄。それを許容したから「もう、社会では普通のことになった」と片付けられてもねえ。
それは非常に「特殊な例」にすぎないのに。

そりゃ、お前は新しい機能を使うためには人前で「八丁堀 吉島行き バス停」みたいにブツブツ言えるんだろうけど、その感覚は「異常」だから。平気でそういうこと出来るヤツ、「一般的」じゃないから(笑)

普通の人は人前でブツブツ言うの、違和感ありまくりだからね。それを「感覚が古い」とか「保守的」とか「新しいものを学ぼうという姿勢にかける」とか、そういう風に言うてごまかしちゃうから駄目なのよ。
はっきり言って、「人前で音声でデバイス操作を行うことは全然恥ずかしくない」という人はそこ止まりだからね。技術者としては却って問題があるわ(笑)

「新しいものを勉強したくてオピニオンリーダーとして新しいものに飛びつく」のは正しいと思うが、そこで自分が「単なるオピニオンリーダー気質」であることを忘れ、周りの人がその商品を否定するから「わかってない」「感覚が古い」と他人を批判し、自己肯定するしかなくなるのよ。
お前が非難している「古い人」の感覚こそがまともで、お前が実は「イノベーターではなく単なる異常者」という事実を冷静に認めることが出来るか否か・・・ここが肝要。

「自分は異常者。他の一般の人に使ってもらうには」という感覚を、技術者やそれを記事にする記者などにはちゃんと持っておいてほしいね。

そこから次のステップへの扉が開くわけだから。
VB.NET + VB-Report 環境での話。

VB-Report というのは Excel で帳票設計できるアドバンスソフトウェア製の帳票作成ツールで、例えば、Excel シートのあるセルに **Hoge とタグを書いておけば、VB.NET のプログラム内で、

Cell("**Hoge", 0, 0).Value = "ほげ"

と書けば、**Hoge と書かれたセルの位置に「ほげ」という文字が印刷される。

Cell("**Hoge", 0, 1).Value = "ほげほげ"

と書けば、その1行下に「ほげほげ」という文字が印刷される。

Excel の「セルの書式設定」で設定した属性もちゃんと効く。
例えば、「文字の制御」の「縮小して全体を表示する」にチェックを入れておけば、そのセルに長い文字が入れば、Excel でそうであるように、帳票も文字が縮小される。

・・・が、例えば文字を打つ位置が固定ではない場合がある。
合計表示をする部分だけ太字にしたいんだけど、明細行数は決まってないから、どのセルが合計表示セルになるかわからない・・・みたいなケース。
こういう時は、プログラム内で属性をセットしてやることもできる。

Cell("**Goukei", 0, i).Attr.FontStyle = VBReport8.FontStyle.Bold

これで、そのセルの文字は Bold(太字)になる。

あと、良く使うのは上にも書いた縮小表示か。

Cell("**Hoge", 0, 1).Attr.ShrinkToFit = True

こんな感じ。
セルの結合もできる。

Pos(4, 10, 8, 12).Attr.MergeCells = True

上の例は、 4列目の 10行目から 8列目の 12行目までを結合しろということ。**Hoge のように名前を付けたセルを基準にせず、直接 X,Y の座標でセルを指定した場合は、Cell オブジェクトではなく Pos オブジェクトを使う。セル名を使って、

Cell("D10", "H12").Attr.MergeCells = True

のようにもできるけど。
セルの連結をして、更に「縮小して全体を表示する」にしたい場合は、

Pos(4, 10, 8, 12).Attr.MergeCells = True
Pos(4, 10, 8, 12).Attr.ShrinkToFit = True

のように続けて書けばいい。

ちなみに、インターネット上で VB-Report についてググると、バージョン 3 の頃の情報がやたらヒットする。
その頃が VB-Report の全盛期だったのだろうか???(^^;
バージョン 3 と 8 ではプロパティ名等が全然違うので、ググった結果が全然役に立たないことも多い。
「書いてあるとおりのプロパティが設定できんやん!!?」という時は、大概バージョン違いの情報を見ているので注意ね。
いやあ、久しぶりに規模的にヤバいセキュリティ問題発生っすねえ。

だって、bash が入ってない UNIX マシンなんか無いやろ?いや、あるだろうけど、相当の変わり者のマシンだろ、それ。

OS の開発元(Linux の各ディストリビュータとか)からのパッチや、修正版パッケージの提供があればいいけど、ないとソースから make し直しか。それだと影響範囲の調査とか面倒くさそう・・・

ということで、取り敢えずうちのテストサーバで対応作業を確認してみた。

このテストサーバに入っている bash が、

# rpm -aq|grep bash
bash-3.2-32.el5

ということで、もろに問題のある Bash 3.2系(^^;
OS は CentOS release 5.8 (Final)なので、[CentOS-announce] CESA-2014:1306 Important CentOS 5 bash Security Update を確認してみると、セキュリティパッチの当たったパッケージ bash-3.2-33.el5_10.4.x86_64.rpm が提供されているようだ。

yum で確認してみる。

# yum list|grep bash
bash.x86_64                            3.2-32.el5                 installed
bash.x86_64                            3.2-33.el5_10.4            updates

ふむふむ。
updates だけ確認するときは、

# yum list updates|grep bash
bash.x86_64                       3.2-33.el5_10.4                     updates

でもOK。
おお、確かに updates ってことで、3.2-33.el5_10.4 が提供されている。

取り敢えず 3.2-33.el5_10.4 をインストール。
途中で依存関係を確認したいので、-y オプションは無しで。

# yum update bash
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * addons: ftp.iij.ad.jp
 * base: ftp.iij.ad.jp
 * centosplus: ftp.iij.ad.jp
 * contrib: ftp.iij.ad.jp
 * extras: ftp.iij.ad.jp
 * updates: ftp.iij.ad.jp
Excluding Packages in global exclude list
Finished
Setting up Update Process
Resolving Dependencies
--> Running transaction check
---> Package bash.x86_64 0:3.2-33.el5_10.4 set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

=======================================================================================================================================================================================
 Package                                 Arch                                      Version                                            Repository                                  Size
=======================================================================================================================================================================================
Updating:
 bash                                    x86_64                                    3.2-33.el5_10.4                                    updates                                    1.8 M

Transaction Summary
=======================================================================================================================================================================================
Install       0 Package(s)
Upgrade       1 Package(s)

Total download size: 1.8 M
Is this ok [y/N]: 

特に他のソフトが update されてしまうということは無いみたい。それなら問題ないので y を入力して先に進む。

Downloading Packages:
bash-3.2-33.el5_10.4.x86_64.rpm                                                                                                                                 | 1.8 MB     00:00
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Updating       : bash                                                                                                                                                            1/2
  Cleanup        : bash                                                                                                                                                            2/2

Updated:
  bash.x86_64 0:3.2-33.el5_10.4

Complete!

インストールされたか確認。

# rpm -aq|grep bash
bash-3.2-33.el5_10.4

バッチリね。
CentOS はパッチ適用済みのパッケージが提供されているので対応も簡単にすみそう。

ちなみに、bash シェルにリモートログインして上記作業を行っても(bash の入れ替えをしても)、途中で回線が切れちゃうなんてことはないのでご安心を。
VB.NET で、データセットから作成したビューのレコードを、ループさせながらインデックス指定で直接削除すんなよという話。

インデックスを指定してレコードを削除する場合も、例えば、

view.AllowDelete = True
Do
    Dim i As Integer = view.Find("消したいレコードに含まれているキーワード")
    If i <> -1 Then
        view.Delete(i)
    Else
        Exit Do
    End If
Loop

みたいな使い方であれば問題ないんだけど、ループしながらインデックスをアップしつつ消しちゃうと、その瞬間にレコードが削除されたことでその後のレコードのインデックスが変化してしまい、正常にデリートできない(削除予定のレコードが並んでいた場合、次のレコードを飛ばしちゃうことになっちゃう)という話。
ビューの Delete メソッドは直接レコードを削除しちゃうんだよね。

例えば、

view.AllowDelete = True
Dim max As Integer = view.Count - 1
For i = 0 To max
    if view(i).hoge = "消したいレコードに含まれているキーワード" Then
        view(i).Delete()
    End If
Next

みたいにしちゃうと、view(i).Delete() しちゃった時点で、以降のレコードのインデックスがひとつ減っちゃう。
本来、view(i + 1) だったレコードが view(i) になっちゃうということ。
つまり、上に書いたように、削除予定のレコードが並んでた場合、削除したレコードの次のレコードの処理は飛ばされてしまうということだ。あかん。

どうしてもビューの中身を頭から舐めながら処理を行いたい場合は、一旦データテーブル等にコピーして処理を行う必要がある。

Dim dt As HogehogeDs.hogeDataTable = CType(view.Table, HogehogeDs.hogeDataTable)
Dim max As Integer = dt.Count - 1
For i = 0 To max
    If dt(i).hoge = "消したいレコードに含まれているキーワード" Then
        dt(i).Delete()
    End If
Next
dt.AcceptChanges()
view = dt.DefaultView

みたいな感じ。

データテーブルの Delete メソッドはビューと違って「実際に削除するのではなく、削除マークをつけるだけなので、最後に AcceptChanges するまではインデックスが変化することもなく、問題なく最後まで削除処理を行うことができる。

これも、知らずにやっちゃうと相当ハマる。特に、レコード件数が多い時はデバッグで問題を見つけ出すのも大変(^^;
今やってる仕事、帳票の出力には VB-Report 8 を使っている。
これ、帳票定義が Excel シートで作成出来るスグレモノなんだけど(Excel でセルを結合したり、罫線を引いたりして帳票のデザインを行ったら、あとは簡単なプログラムで帳票出力できる)、意外にネット上に情報がなくて俺みたいな初めて使うもんには困るわあ。

情報が無いっつうか、古いんだよな。だいたい、Ver 3 の頃の情報ばっか引っかかる。

開発ツールについてきてるヘルプを使えば良いっつう話なんだけど、このヘルプがこれまたなかなか情報までたどり着きづらいというか(^^;(あくまで、俺みたいに初めて使う人間の意見だけど)

Ver 3 の頃と 8 では大きくプロパティが変わってるんだけど、ヘルプの検索でもなかなか引っかからなくて弱った(^^;
例えばプログラムの中で動的に「セルの結合」がしたかったんだけど、「キーワード」や「検索」で「セル結合」とか入れてもなんもヒットせんし(^^;

結局、

【セルの結合】
3.0 Report.Pos(x1, y1, x2, y2).Attr.Joint = True
 ↓
8.0 Report.Pos(x1, y1, x2, y2).Attr.MergeCells = True

みたいに変わってたんだけど、「Joint」とか入れてもヘルプじゃなんもヒットせんしさあ。
こういうの、過去のバージョンの内容と変わったものについてもっと考慮してほしいなあ。

【縮小して全体表示】
3.0 Report.Pos(x1, y1).Attr.Fit = True
 ↓
8.0 Report.Pos(x1, y1).Attr.ShrinkToFit = True

これも、「Fit」じゃ何の情報も見つからなくて、もちろん「ShrinkToFit」って入れればヒットするんだけど(^^;
「ShrinkToFit」がわかんないから検索してんのに(^^;

まあ、さすがにこれだけ名前が変わってるってのがわかれば、PosHorz は、プロパティの一覧を頭から舐めていって、ああ、この HorizontalAlignment に変わったんだろうなあと想像はつくが・・・

ちなみに、中央揃えは、

Report.Pos(x1, y2).Attr.HorizontalAlignment = VBReport8.HorizontalAlignment.Center

だ。
VB.NET の話。

DataSet には並び替えの概念はないので、DataSet の表をソートしようとすると、その DataSet から DataView を作って、それを Sort メソッドで並び替えるしか無いわけだけど、検索(行の抽出)だけであれば DataSet の中で行える。

昨日アップしたエントリーでは、

Dim dv As DataView = ds.hoge_table.DefaultView
dv.RowFilter = "hoge_time >= #" & hogeTime.ToString & ".00000# Or hoge_time <= #" & hogeTime.ToString & ".99999#"
dv.Sort = "key1, key2"
For Each drv As DataRowView In dv
    Dim dr As HogehogeDataSet.hoge_tableRow = CType(drv.Row, HogehogeDataSet.hoge_tableRow)
    dr.key1 をほげほげ~
Next

という処理のことを書いたけど、この Sort メソッドを実行しない・・・という前提なら(つまり検索(抽出)をしたいだけなら)、DataTable の Select メソッドを使えば、検索(抽出)した結果が配列で取れるので、

Dim filter As New Text.StringBuilder
filter.Append("hoge_time >= #" & hogeTime.ToString & ".00000# Or hoge_time <= #" & hogeTime.ToString & ".99999#")
Dim drList() As DataRow = ds.hoge_table.Select(filter.ToString)
For Each dr As HogehogeDataSet.hoge_tableRow In drList
    dr.key1 をほげほげ~
Next

という感じで良い。

ステップ数は変わらないけど、抽出のためだけにビューを作らないので俺はこっちの方が好みだな。
ソートする時はどうしようもないけど(^^;

一応、メモ代わりに書いとくなり。
結局、これってミリ秒までマッチングする必要がないのなら、格納時に、

Dim hogeTime As DateTime = Now

じゃなく、

Dim hogeTime As DateTime = CDate(Now.ToString)

みたいにして、ミリ秒を削った時間(まあ、実際は 0ミリ秒になるってことだけど)をセットしてやれってことか。

こうすると、hogeTime には実際の時刻が 2014/09/04 18:37:36.5685248 であろうと、2014/09/04 18:37:36.0000000 という値がセットされるので、

dv.RowFilter = "hoge_time = #" & hogeTime & "#"

という条件でマッチングするようになる。

dv.RowFilter = "hoge_time >= #" & hogeTime.ToString & ".00000# Or hoge_time <= #" & hogeTime.ToString & ".99999#"

みたいに長ったらしい条件書かなくてもいい。

つーか、この長ったらしい条件、やっぱダメだよね。
例えば、これじゃあ 2014/09/04 18:37:36.9999999(小数点以下 7桁)の時間はマッチしないよね。条件が <= 2014/09/04 18:37:36.99999(小数点以下 5桁)だから。18:37:36.9999900 ってことだもんね。
いや、それは小数点以下の桁数を 7桁にして <= 2014/09/04 18:37:36.9999999 となるようにすればいいやん・・・と思うかもしれんけど、小数点以下の最大桁数って、これ、絶対固定なの?

今、仕事で使っている Windows 8.1 Pro(64bit)の VB.NET で確認すると、7桁まで取れるようなんだけど(ToString("yyyy/MM/dd HH:mm:ss.FFFFFFFF") みたいにミリ秒以下を 8桁にすると例外エラーで落ちる)、これ、32bit 版でも一緒なの?あるいは、今後 CPU のビット数や OS のバージョンが上がっても、絶対 7桁なの?12桁とかにならないの?

そのあたりが担保できない限り、やっぱミリ数は含めるべきじゃないよね。青天井で桁数増えていく可能性あるんだから。この辺、「Microsoft の勝手」の世界だよね?
今は <= 2014/09/04 18:37:36.9999999 が有効でも、何年か後はわからんってことよね。

ということで、時間は CDate(Now.ToString) して突っ込んじゃうのが一番安全そう。

「業務アプリケーション」でミリ秒まで必要なケースって糞レアだからな(笑)

このアーカイブについて

このページには、過去に書かれたブログ記事のうちお仕事カテゴリに属しているものが含まれています。

前のカテゴリはいつかカープを買う日です。

次のカテゴリはお店です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

電気ウナギ的○○ mobile ver.

携帯版「電気ウナギ的○○」はこちら