MW211 EXIT

devlog
MicrosoftExcel/プルダウンメニュー
2013年06月27日
プルダウンメニューを設置したいセルを選択して、
「データ→データの入力規則→データの入力規則」を選ぶ。
┌──────────────────────────────────────┐
│データの入力規則                                                            │
├──────────────────────────────────────┤
│┌──┐──┐──┐──┐                                                  │
││設定│    │    │    │                                                  │
││    └─────────────────────────────────┐│
││条件の設定───────────────────────────────││
││入力値の種類                                                            ││
││┌──────┬─┐  ■空白を無視する                                  ││
│││リスト      │▼│                                                    ││
││└──────┴─┘  ■ドロップダウンリストから選択する                ││
││データ                                                                  ││
││┌──────┬─┐                                                    ││
│││            │  │                                                    ││
││└──────┴─┘                                                    ││
││元の値                                                                  ││
││┌────────────────────────────────┬─┐││
│││男,女,その他                                                    │■│││
││└────────────────────────────────┴─┘││
│└──────────────────────┌─────┐┌─────┐┘│
│                                              │    OK    ││キャンセル│  │
└───────────────────────└─────┘└─────┘─┘
「入力値の種類」を「リスト」にして、「元の値」にCSV形式でデータを登録すればOK。
分類:Excel
C言語/規格の歴史
2013年06月26日
┌──┬───────────────────────────────────┐
│K&R │書籍「The C Programming Language」(K&R)が事実上の標準     (1978年出版)│
├──┼───────────────────────────────────┤
│C89 │・関数プロトタイプの導入                                              │
│C90 │・void型、enum型の追加                                                │
│    │「ANSI C89」「ISO C90」とも呼ばれ、「JIS X3010-1993」が該当           │
├──┼───────────────────────────────────┤
│C95 │・ワイド文字版ライブラリを追加                                        │
├──┼───────────────────────────────────┤
│C99 │・変数宣言位置の自由化(ブロック先頭でなくてもよい)                    │
│    │・論理型(_Bool型)の追加「stdbool.h」                                  │
│    │・複素数の追加「complex.h」                                           │
│    │・64ビット整数値(「long long int 型」)の追加                          │
│    │・「//」コメントの導入                                                │
│    │・インライン関数の導入                                                │
│    │・可変長配列の導入                                                    │
│    │「JIS X 3010:2003」が該当                                             │
├──┼───────────────────────────────────┤
│C11 │最新規格                                                              │
│    │・「gets()」関数の廃止                                                │
│    │・Unicode文字列の標準対応                                             │
│    │・type-generic式の導入                                                │
│    │・無名構造体・無名共用体の導入                                        │
│    │・排他的アクセスによるファイルオープン方法の実装                      │
│    │・_Noreturn関数指示子の導入(スタックを消費しない関数)                 │
└──┴───────────────────────────────────┘
分類:C/C++
PostgreSQL/表結合のUSING句
2013年06月24日
┌──────────────────────────────────────┐
│SELECT 列                                                                   │
│    FROM 表1                                                                │
│        LEFT JOIN 表2                                                       │
│          ON 表2.キー = 表1.キー                                            │
└──────────────────────────────────────┘
こんな場合…
┌──────────────────────────────────────┐
│SELECT 列                                                                   │
│    FROM 表1                                                                │
│        LEFT JOIN 表2                                                       │
│          USING (キー);                                                     │
└──────────────────────────────────────┘
こんな風に書ける。

列名が同じなら、USING句が使える(括弧も忘れずに)。

ちなみにこんな風に…
┌──────────────────────────────────────┐
│SELECT 列                                                                   │
│    FROM 表1                                                                │
│        LEFT JOIN 表2                                                       │
│          USING (キー1, キー2);                                             │
└──────────────────────────────────────┘
複数指定も可能。

これは、以下相当となる。
┌──────────────────────────────────────┐
│SELECT 列                                                                   │
│    FROM 表1                                                                │
│        LEFT JOIN 表2                                                       │
│          ON  表2.キー1 = 表1.キー1                                         │
│          AND 表2.キー2 = 表1.キー2;                                        │
└──────────────────────────────────────┘
条件が「AND」なのか「OR」なのか一瞬悩んでしまうが
「OR」で結合してもほとんど意味をなさないので(かなり無秩序な結果)、
おのずと「AND」相当だということがわかる(わかってくる)。
分類:PostgreSQL
Smarty/JavaScriptのベタ書きはちょっと
2013年06月23日
┌──────────────────────────────────────┐
│if (true) {                                                                 │
│    alert("メッセージ");                                                    │
│}                                                                           │
└──────────────────────────────────────┘
上記のようなif文を、一直線に書きたい衝動にかられることがある。
┌──────────────────────────────────────┐
│if (true) {alert("メッセージ");}                                            │
└──────────────────────────────────────┘
if文がいくつも並ぶ場合には行比較の観点からも便利な場合がある。

しかし、これをSmartyテンプレート上で行ってはいけない。
なぜなら「{~}」はSmartyではSmarty変数等を記述する領域だからだ。
つまり「{alert("メッセージ");}」の部分を誤認識してしまう。

解決策としては最初のように改行して一直線に「{…}」とならないようにするか、
JavaScriptのソースファイルを外部ファイルとしてしまうかだ。
分類:Smarty
PostgreSQL/SQL上でトランザクション処理
2013年06月17日
「pgAdmin」の「Query」などからトランザクション処理を再現するには、
以下のようなSQL文を順番に実行すればよい。
┌──────────────────────────────────────┐
│BEGIN;                                                                      │
├──────────────────────────────────────┤
│(SQL文;)                                                                    │
├──────────────────────────────────────┤
│COMMIT;                                                                     │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│BEGIN;                                                                      │
├──────────────────────────────────────┤
│(SQL文;)                                                                    │
├──────────────────────────────────────┤
│ROLLBACK;                                                                   │
└──────────────────────────────────────┘
「BEGIN」でトランザクションが開始して、「COMMIT」または「ROLLBACK」で終了。
もちろん、「COMMIT」はトランザクション中の処理を履行して、
「ROLLBACK」は取り消す。

終了せずに再度開始(「BEGIN」を二回続けて実行など)すると、
以下のようなワーニングメッセージが出るが、問題はないようだ。
┌──────────────────────────────────────┐
│WARNING:  there is already a transaction in progress                        │
└──────────────────────────────────────┘
分類:PostgreSQL
PostgreSQL/pg_dumpのパスワード
2013年06月16日
pg_dumpを実行した直後に以下のようにパスワード入力を促される。
┌──────────────────────────────────────┐
│>pg_dump -U ユーザID データベース名 > バックアップファイル.sql              │
│パスワード:                                                                 │
└──────────────────────────────────────┘

これをバッチで自動化する場合には、パスワード設定ファイルってのを
書き換えればいいらしい。
┌──────────────────────────────────────┐
│>ECHO localhost:5432:*:ユーザID:パスワード>                                 │
│                                          "%APPDATA%\postgresql\pgpass.conf"│
└──────────────────────────────────────┘

ただし、書き換えた後に設定を元に戻した方がいいので、
「pgpass.conf」の中身を控えておいた方がよい。
「%APPDATA%」の部分はWindowsの環境変数として定義してるので、
「echo」コマンドで確認すればよい。
┌──────────────────────────────────────┐
│>echo "%APPDATA%"                                                           │
│C:\Users\xxxx\AppData\Roaming                                               │
└──────────────────────────────────────┘

なお、これを自動化するならば、以下のように「pgpass.bak」(名称は任意)に
退避して戻すって感じか。
┌──────────────────────────────────────┐
│>COPY /Y "%APPDATA%\postgresql\pgpass.conf"                                 │
│                                           "%APPDATA%\postgresql\pgpass.bak"│
├──────────────────────────────────────┤
│>ECHO localhost:5432:*:ユーザID:パスワード>                                 │
│                                          "%APPDATA%\postgresql\pgpass.conf"│
├──────────────────────────────────────┤
│pg_dump -U ユーザID データベース名 > バックアップファイル.sql               │
├──────────────────────────────────────┤
│>MOVE /Y "%APPDATA%\postgresql\pgpass.bak"                                  │
│                                          "%APPDATA%\postgresql\pgpass.conf"│
└──────────────────────────────────────┘
分類:PostgreSQL
PHP/大容量POSTの制限
2013年06月15日
「php.ini」で制限をかける項目としては以下があるが、
以下のような性格の違いがある。
┌───────┬────────────┬─────────────────┐
│max_input_vars│POSTパラメータ数の上限  │上限数までは送信される            │
├───────┼────────────┼─────────────────┤
│post_max_size │POSTサイズの上限        │全て送信されない                  │
└───────┴────────────┴─────────────────┘
分類:PHP
PostgreSQL/regexp_replace()の最短一致
2013年06月14日
「regexp_replace()」では基本最長一致で置換される。
「.*」や「.+」の場合、最短一致にするには末尾に「?」を付ければいいようだ。

例えば、LF改行で特定の行を置換するにはこんな感じとなる。
┌──────────────────────────────────────┐
│UPDATE 表 SET 列 = regexp_replace(列,                                       │
│                                  '見出:.*?' || chr(10),                   │
│                                  '見出:'    || chr(10));                  │
└──────────────────────────────────────┘

例えば、CRLF改行の場合はこう。
┌──────────────────────────────────────┐
│UPDATE 表 SET 列 = regexp_replace(列,                                       │
│                                  '見出:.*?' || chr(13) || chr(10),        │
│                                  '見出:'    || chr(13) || chr(10));       │
└──────────────────────────────────────┘
分類:PostgreSQL
PostgreSQL/勤怠管理(2)
2013年06月13日
テストデータを使って別のアプローチで勤務時間を計算してみよう。

まずは前回同様、「09:00~18:00」勤務で「12:00~13:00」休憩の場合。
┌──────────────────────────────────────┐
│WITH "test"("start",                                                        │
│            "end"  ) AS (                                                   │
│         VALUES('09:00'::time,                                              │
│                '18:00'::time)                                              │
│     )                                                                      │
│SELECT trunc((extract(EPOCH FROM '12:00'::time - "start"::time)             │
│            + extract(EPOCH FROM "end"         - '13:00'::time)) / 60)      │
│    FROM "test";                                                            │
└──────────────────────────────────────┘
続いて、さらに「18:00~18:30」の休憩をはさんで「18:30~21:30」が平常残業、
「21:30~22:00」の休憩をはさんで「22:00~24:00」が深夜残業の場合。
以下のように時間帯マスタを駆使して計算が可能だ。
┌──────────────────────────────────────┐
│WITH "t"("s",                                                               │
│         "e"  ) AS (                                                        │
│         VALUES('09:30'::time,                                              │
│                '22:30'::time)                                              │
│     ),                                                                     │
│     "r"("s1",                                                              │
│         "e1"  ,                                                            │
│         "s2",                                                              │
│         "e2",                                                              │
│         "s3",                                                              │
│         "e3"  ,                                                            │
│         "s4",                                                              │
│         "e4"  ) AS (                                                       │
│         VALUES('09:00'::time,                                              │
│                '12:00'::time,                                              │
│                '13:00'::time,                                              │
│                '18:00'::time,                                              │
│                '18:30'::time,                                              │
│                '21:30'::time,                                              │
│                '22:00'::time,                                              │
│                '23:00'::time)                                              │
│     )                                                                      │
│SELECT CASE WHEN "t1" > 0 THEN "t1" ELSE 0 END AS "平常",                   │
│       CASE WHEN "t2" > 0 THEN "t2" ELSE 0 END AS "残業",                   │
│       CASE WHEN "t3" > 0 THEN "t3" ELSE 0 END AS "深夜",                   │
│       "t0" - "t1"                             AS "欠勤"                    │
│  FROM (                                                                    │
│    SELECT trunc((extract(EPOCH FROM "e1" - "s1")                           │
│                + extract(EPOCH FROM "e2" - "s2")) / 60) AS "t1",           │
│           trunc((extract(EPOCH FROM "e3" - "s3")) / 60) AS "t2",           │
│           trunc((extract(EPOCH FROM "e4" - "s4")) / 60) AS "t3",           │
│           "t0"                                                             │
│      FROM (                                                                │
│        SELECT CASE WHEN t.s < r.s1 THEN r.s1 ELSE t.s END AS "s1",         │
│               CASE WHEN t.e > r.e1 THEN r.e1 ELSE t.e END AS "e1",         │
│               CASE WHEN t.s < r.s2 THEN r.s2 ELSE t.s END AS "s2",         │
│               CASE WHEN t.e > r.e2 THEN r.e2 ELSE t.e END AS "e2",         │
│               CASE WHEN t.s < r.s3 THEN r.s3 ELSE t.s END AS "s3",         │
│               CASE WHEN t.e > r.e3 THEN r.e3 ELSE t.e END AS "e3",         │
│               CASE WHEN t.s < r.s4 THEN r.s4 ELSE t.s END AS "s4",         │
│               CASE WHEN t.e > r.e4 THEN r.e4 ELSE t.e END AS "e4",         │
│               trunc((extract(EPOCH FROM "e1" - "s1")                       │
│                    + extract(EPOCH FROM "e2" - "s2")) / 60) AS "t0"        │
│            FROM t,r                                                        │
│      ) AS "z1"                                                             │
│  ) AS "z2"                                                                 │
└──────────────────────────────────────┘
ただし、翌朝深夜残業が…。「time」型は「25:00」とかいう概念がない…。
分類:PostgreSQL
PostgreSQL/勤怠管理(1)
2013年06月12日
例えば「09:00」に出社し、「18:00」に退社した日の労働時間を
分単位で求めたいとする。
で、だいたい「12:00~13:00」はお昼休みで1時間休憩だったりして
8時間(480分)労働だったりするわけだ。
これをSQL文で求めるとこんな感じになる。
┌──────────────────────────────────────┐
│SELECT trunc((extract(EPOCH FROM '18:00'::time - '09:00'::time)             │
│            - extract(EPOCH FROM '13:00'::time - '12:00'::time)) / 60);     │
└──────────────────────────────────────┘
中身を説明すると…。
「time」型はタイムスタンプとは違って時間のみを管理する便利な型だ。
で、これをそのまま減算することにより、経過時間が取得できる
その経過時間は「interval」型という特殊な型なので、
これを分に換算する訳だが、「extract(EPOCH FROM …」で秒にしか換算できない
よってここからは自力で、60秒で割って「trunc()」で
端数を切り捨てるってことをしている。
でこれを、「総勤務時間-休憩時間」で差し引きすると労働時間が求まるって寸法だ。

実際に倣って差し引きを分単位で行いたいって場合なら、
おのおので一旦分換算するというのもある。
┌──────────────────────────────────────┐
│SELECT trunc((extract(EPOCH FROM '18:00'::time - '09:00'::time)) / 60)      │
│     - trunc((extract(EPOCH FROM '13:00'::time - '12:00'::time)) / 60);     │
└──────────────────────────────────────┘

お昼休みは特に時間帯は決まっていなくて
とにかく1時間休める(混んでない時に飯にいける)って場合であれば
経過時間をそのまま使えばよい
┌──────────────────────────────────────┐
│SELECT trunc((extract(EPOCH FROM '18:00'::time - '09:00'::time)             │
│            - extract(EPOCH FROM '01:00'::time                )) / 60);     │
└──────────────────────────────────────┘

ということで、これがわかれば、今ベタで書いている時間の部分を
「time」型のデータに置き換えて(なんなら文字型データをキャストしてもよいが)
労働時間の計算が自由自在にできてしまいそうだ。
分類:PostgreSQL
前へ 1 … 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 … 156 次へ