[Excel] 画像の貼り付け方法とデータサイズの圧縮についての Tips

Excel のシートに画像を貼り付ける一番手っ取り早い方法は、クリップボードに画像をコピーした後、シート上にペーストする方法だろう。ただし、この方法では、画像は bmp (ビットマップ) 形式で貼り付けられる。画像を大量に貼り付けていくと、それに伴って Excel ファイルそのもののサイズが肥大化していくうえ、図の圧縮 (書式 - 図の圧縮) ができない。

画像を貼り付ける際は、[挿入] - [図] で、画像ファイルを貼り付けていく方法の方が、データサイズという観点ではより望ましい。この方法であれば、データサイズを圧縮することができる。

エビデンス作成時に大量の画像ファイルを貼り付ける場合には、キャプチャソフトの設定をファイルとして出力するようにしたほうがよさそうだ。

[Excel] データ個数を数える

範囲内のセルに入力されている (空白ではない) セルがいくつあるかどうか数える関数。

A1 から A10 のセルで空白ではないセルをカウント (範囲は複数列を指定できる)。
=COUNTA(A1:A10)

[FUJITSU] ノート PC のキーボードからテンキーを設定・解除

アルファベット部分をテンキーに設定することができるノート PC も多い。
しかし、いつの間にか設定が変わっていて、英字が入力できん! となる場合がある。

メーカーによって若干異なっているので統一感がないように思うのだが、FUJITSU の場合は、Num Lk キーで設定・解除ができた。

[UT, IT, ST] 開発時のテストフェーズについて

システム開発においては、バグは必ずあるものとして考え、それをより早い段階で発見するこが望ましい。そういった意味では、テスト工程はコーディングを行うよりも重要であると思う。
プロジェクトでは以下のようなフェーズでテストを行っていくことが多い。
なお、以下は経験上の話であることをお断りしておく。

UT (Unit testing) = 単体テスト

プログラミングによって手を入れた部分のみを対象としたテスト。
ページ単位、画面単位で完結している。

ここでは基本的なバグについて注意を払わなければならないのだが、この段階で徹底的にバグをつぶしておくことが理想であると思う。
見積もりの段階でテスト込みの工数算出を行うべきであり、(経験から言うと) この部分をないがしろにしている (充分な期間を取っていない、テスト方針が定まっていない等) プロジェクトは、後のフェーズで炎上する確率が非常に高い。

データの出入力がある場合、最小値と最大値の入力を行って、データベースアクセスの部分はデータ型によるオーバーフローや NULL のチェック、想定した通りの登録や更新・削除が確実に行われているかどうかは特に気をつける。
異なるシステム (古いシステムの移行等) からのデータ移行がある場合は、文字コードによるバグなどもよくあるので、どのようなデータが入っているのか確認しておいたほうが良い。

このテストでは、テストを自動化している場合も多いだろうが、
基本的な観点を理解していないと成果が出ない。

IT (Integration testing) = 結合テスト

修正を行った部分をシステムに組み込んでみて、
それぞれがどういった影響を及ぼすかの検証を行う。

ここからは、テスト時に「シナリオ」を作成するだろう。
シナリオとは、いわばユーザーの振る舞いであり、システム稼動後にユーザーがどのような操作をするのか、今回修正対象となった部分はどのような動作を想定しているのかを具体的なイメージをもってテストケースを作成する。

プロジェクトの方針によってシナリオの書き方は変わってくるだろうが、特にデータベースへの登録や更新、削除などの一蓮の流れに重点を置いてシナリオが書かれることが多い。

ウェブシステムの場合は、ページの遷移が肝となるが、
セッションの管理なども特に気をつけてテストしなければならない。

新規のシステムを作っている場合を除き、修正を行っていない部分に新たなバグが発生していないか気をつけなければならない。今回修正したことによって新しいバグが生まれてしまっている場合も多いからだ。

ST (System testing) = システムテスト

プロジェクトによっては結合テストと一緒になっていることも多いが、今回のプロジェクトの対象となるシステムが、他のシステムと相互に影響を与えている規模の大きなシステムの場合は、このテストを行う。

今回対象となる A システムで登録したデータなどを B システムでも参照していたりする場合には、その部分の連結にバグがないかどうかをテストする。

結合テストと同じくシナリオに沿ってテストが行われ、内容的にも近いものがあるが、より実稼働環境に近い動きを想定しテストを行う。

UAT (User acceptance testing) = 受け入れテスト

納品先のユーザーにシステムを操作してもらうフェーズである。
ただし、このフェーズではユーザーにテストをしてもらうというよりも、ユーザーが想定している要望通りの動作をしているかどうかのチェックの意味合いが強い。
また、ここまでくると外部の人間はプロジェクトから離れることも多々ある。

ユーザーは操作性やデザインなどの細かい部分について要望を出してくる場合もあるが、要望をすべて聞いているとシステムが完成しない。また、実装を根底から覆すような要望もよくある。

期限を設けることや、バグ以外の要望は次のプロジェクトが立ち上がった際の課題とするように検討するべきだ。
このあたりは契約によって異なるが、リーダーがイエスマンだったり、立場上 断りにくいポジションにある会社の場合は、無理な注文でもさらに対応しなければならず、結果として炎上する話もよくある。


テストは実際の現場の方針によって左右される部分が大きいが、
できるだけ初期の段階で不具合をつぶしていくことが大事である。

[Excel] ブックのファイル名とパスを取得する cell ( filename ) 関数

現在の Excel ブックのファイル名とパスをシートに表示させたいときには、CELL で filename を指定する。

=CELL("filename",A1)

しかし、注意しなければならないのが、この関数はファイルをいったん保存しないと空白 (空) が返ってくる。これは、保存してあるファイルであっても右クリックから 「新規作成」 しても同様である。

保存することでファイルのパスが通り、ファイル名とパスが表示される。

[SQL Server] データが重複してしているレコードを抽出する

どの値が重複しているか不明で、そのレコードを取得したい場合は、以下のような条件で検索する。
なお、この例では、一時テーブルを使用している。
CREATE TABLE #T1
(
 ID NUMERIC(3)
 ,GIVEN_NAME NVARCHAR(50) 
)

INSERT INTO #T1 (ID,GIVEN_NAME)
VALUES (11,'Taro'),(12,'Jiro'),(100,'Saburo'),(11,'Siro'),(15,'Goro'),(100,'Rokuro'),(17,'Sitiro')

-- ID が重複しているレコードを抽出する。
SELECT * FROM #T1 T1
WHERE EXISTS
(
 SELECT ID FROM #T1
 WHERE T1.ID = #T1.ID
 GROUP BY #T1.ID
 HAVING COUNT(*) > 1
 
)
ORDER BY ID

DROP TABLE #T1

結果は以下のようになる。
ID が 11 と 100 のレコードで重複が発生していることがわかった。
ID                                      GIVEN_NAME
----------------------- -----------------------
11                                      Taro
11                                      Siro
100                                     Rokuro
100                                     Saburo

(4 行処理されました)

[SQL Server] データベースのテーブルやビューなどの一覧を取得する

-- テーブル一覧を取得。
SELECT NAME FROM SYSOBJECTS WHERE XTYPE = 'U';

-- ビュー一覧を取得。
SELECT NAME FROM SYSOBJECTS WHERE XTYPE = 'V';

-- ストアド一覧を取得。
SELECT NAME FROM SYSOBJECTS WHERE XTYPE = 'P';

-- シノニム一覧を取得。
SELECT NAME FROM SYSOBJECTS WHERE XTYPE = 'SN';
取得項目は name 以外にも色々とあり、xtype はこれ以外にもある。
システムオブジェクトについての詳しい情報は、以下のページにまとめられている。
sys.sysobjects (Transact-SQL) - TechNet

[SQL Server] テーブルのデータから INSERT 文を生成する

SQL Server Management studio (SSMS) には、テーブルに格納されているデータから INSERT 文を生成する機能がある。
  1. 対象のデータベースを右クリックし、[タスク ] - [スクリプトの生成] をクリック。
  2. 「スクリプトの生成とパブリッシュ」 が表示されるので、画面指示に従う。
  3. 注意点として、このまま画面指示に従っているとテーブルの構造 (スキーマ) しか出力されない。スクリプト生成オプションの設定で、詳細設定ボタンを押下、「スクリプト生成の詳細オプション」画面を表示する。

    ここでかなり細かく出力内容を設定できるのだが、「スクリプトを生成するデータの種類」を「データのみ」に設定すると、INSERT 文のみ出力される。
なお、ファイルに保存以外にも、クリップボードにコピーしたり、新しいクエリウィンドウに出力することもできる。

[Facebook] イベント日時の期間設定

Facebook で新しいイベントを作成する際に、期間を設定したい時がある。
作成時にこの画面を見ただけではどうやるのだろう? と思ってしまう。

これは 終了時間 をクリックすると、もう一つ日付の入力フィールドが表示される。
[ 終了時間 ] の方で期間を設定すれば良い。

パッと見ただけではわかりづらいね。
しかもこういうのは仕様がいきなり変わって変更されていることもあるし。


[Picasa] 右クリックからの 「開く」 に Photoshop を手動で追加

Picasa の便利機能として、右クリックから特定のアプリケーションで開くというものがある。
たいていの場合は登録済みのアプリケーションが表示されるようになっているのだが、Windows のアップグレードを行ったらこの値が変わってしまい、Photoshop で開けなくなってしまった。
調べてみると、Picasa の 「開く(W)」 は、レジストリに登録してあるものを使用しているようだ。
  1. レジストリエディタを起動する。ファイル名を指定して実行 (Windowsキー & R) → regedit
  2. 以下の場所を開く。
    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.jpg\OpenWithList
  3. この例では 「C」の値をペイントから Photoshop.exe に変更した。
ペイントが Photoshop に変更された!<br> 他のアプリケーションも同じ要領で登録できるはず。

[SQL Server] 8115 エラー

numeric をデータ型 numeric に変換中に、算術オーバーフロー エラーが発生しました。

数値型の変換に失敗している。NULL をセットしようとした場合にも発生する。

[SQL Server] 種類 'System.OutOfMemoryException' の例外がスローされました。 (mscorlib)

Management Studio (SSMS) でクエリ実行時に、結果セットが巨大である場合に発生するメモリ不足エラー。大きめのテーブルの結果セット (グリッド) を全選択してそのままコピーしようとすると発生したりする。
32 ビット OS の場合、そもそも SSMS が 2G の制約を受け、かつ、結果をグリッド表示する場合は 64 KB まで。結果をテキスト表示する場合は 8 KB までという制約があるらしい。

解決方法は以下の 3 つだが、最後のコマンドはややハードルが高いが、自動化処理などの応用も利く。

  1. 結果をテキストで表示
    [クエリウィンドウで右クリック] - [結果の出力] -  [結果をテキストで表示]
  2. 結果をファイルに出力
    [クエリウィンドウで右クリック] - [結果の出力] -  [結果をファイルに出力]
  3. sqlcmd ユーティリティの使用
    コマンドラインから SQL を実行する。
    http://technet.microsoft.com/ja-jp/library/ms162773.aspx

[ 参考 ]
"System.OutOfMemoryException" exception when you execute a query in SQL Server Management Studio - Microsoft

[SQL Server] INSERT INTO SELECT で DB 間のテーブルコピー

別の DB でなくても、INSERT 文には他のテーブルの SELECT を使用できる。
-- HAGE テーブルのデータをすべて HOGE テーブルにコピーする。
INSERT INTO HOGE SELECT * HAGE

-- HAGE テーブルの一部のデータ (以下の例だと NAME と AGE) を HOGE テーブルにコピーする。
INSERT INTO HOGE SELECT NAME, AGE HAGE

-- DB が違っていてもコピーできる。
-- HOGE テーブル (dbo 所有 TEST1 データベース) を、すべて HOGE テーブル (dbo 所有 TEST2 データベース) にコピーする。
INSERT INTO TEST1.dbo.HOGE SELECT * TEST2.dbo.HOGE

[SQL Server] Is this the most simply RPAD and LPAD?

Get 20 charactors and RPAD with zero.
SELECT REPLACE(CONVERT(NCHAR(20), 'SQLServer2014-'), SPACE(1), '0')
-- Result : SQLServer2014-000000
Get 20 charactors and LPAD with zero.
SELECT REPLACE(REVERSE(CONVERT(NCHAR(20), REVERSE('SQLServer2014-'))), SPACE(1), '0')
-- Result :  000000SQLServer2014-

[SQL Server] 文字列の空白埋めと 0 埋めを一行で実現

強引な方法だが、独自関数なしに実現してしまう方法。

文字列を 20 文字抜き出す。20 文字以下の場合は後ろを空白で埋める。
SELECT CONVERT(NCHAR(20), 'SQLServer2014-')
-- 結果(後ろに空白がある) : SQLServer2014-    
文字列を 20 文字抜き出し、かつ、20 文字以下の場合は後ろを '0' で埋める (擬似 RPAD)。
SELECT REPLACE(CONVERT(NCHAR(20), 'SQLServer2014-'), SPACE(1), '0')
-- 結果 : SQLServer2014-000000
文字列を 20 文字抜き出し、かつ、20 文字以下の場合は前を '0' で埋める (擬似 LPAD)。
SELECT REPLACE(REVERSE(CONVERT(NCHAR(20), REVERSE('SQLServer2014-'))), SPACE(1), '0')
-- 結果 :  000000SQLServer2014-
素直に関数を作ったほうがいいか……。

[Excel] 一行上のセルを参照する OFFSET 関数


Excel で連番を振ったものの、行の挿入をして下の行番号がすべてズレてしまうことがあるが、OFFSET 関数を使えば常に上の行を参照することができる。

必須パラメータは以下の通り。
OFFSET(参照, 行数, 列数)

参照 : 基準とするセル
行数 : 参照からみた行 (縦)。マイナスを付けると上の行を参照する。
列数 : 参照から見た列 (横)。マイナスが左、プラスが右の列を参照。省略可能。

この例では、A2 から見て一行上を参照してその値に 1 を足す、となる。
=OFFSET(A2, -1, ) + 1

[SQL Server] 文字型の違い (varchar, nvarchar)

業務アプリのデータベース設計では、未だに何も考えずに文字列は varchar で定義してあることが多い。そして、文字はすべからく「全角 2 バイト、半角 1 バイト」である、という概念が未だに残っている現場や技術者が多い。

nchar および nvarchar (Transact-SQL) - msdn
http://msdn.microsoft.com/ja-jp/library/ms186939.aspx

nvarchar は全角であろうが半角であろうが文字数がそのままデータ長になるのだが、それより重要な意味は Unicode をサポートしているということであろう。

What is the difference between char, nchar, varchar, and nvarchar in SQL Server? - Stack Overflow
http://stackoverflow.com/questions/176514/what-is-the-difference-between-char-nchar-varchar-and-nvarchar-in-sql-server

最近の OS、プラットフォームは内部動作として Unicode であることがほとんどであるから、アスキーコードのみサポートされた環境でない限り、nvarchar を採用するほうが無難であるとのこと。
逆に言うと、varchar で定義されているものを nvarchar に変換する際には気をつけないといけない。

[SQL Server] バイト数で文字列を切り出す

SQL Server には LENB のようなバイト数をカウントする関数はないようだが、文字列を切り出すという目的であれば、型変換を利用して擬似的に実現することができる。

先頭から 6 バイト分切り出し。
SELECT CONVERT(VARCHAR(6), 'SQLサーバー2014')
-- 結果 : SQLサ
後ろから 6 バイト切り出すためには、右側から抜き出したい場合は REVERSE 関数で反転させてから抜き出し、さらに戻す。
※ RIGHT 関数はバイト数ではなく、文字数で取得するため使用できない。
SELECT REVERSE(CONVERT(VARCHAR(6), REVERSE('SQLサーバー2014')))
-- 結果 : ー2014

[SQL Server] ストアド名の命名規則についての意外な事実

ストアド名を何気なく 'sp_' から始めているプロジェクトは多岐にわたると思う。しかし、これは実は望ましくないという記事をふと見かけた。

ストアドプロシージャの名前にsp_はダメらしい。
http://blogs.yahoo.co.jp/yottun8/62433363.html

(元記事) Should Stored Procedure name start with SP_ ???
http://www.sqlserver-training.com/should-stored-procedure-name-start-with-sp_/-

SQL Server には、'sp_' から始まるシステムストアドプロシージャがあるが、自分で定義したストアドに関しても接頭語が 'sp_' である場合は、まず master データベースを探すらしい。そのため、ミリ秒の世界ではあるが、遅くなることは遅くなるとか。
ファイルのパスをすべて書くことで master データベースへの検索をさせないらしいのだが、誤差の範囲なのだろう。あまりこのことに触れられているドキュメントは見当たらない。

[ドスパラ PC] 電源は本当に弱いのか?

そんなに長く使うつもりはなかったのだが、未だに 2008 年 6 月に買った ドスパラの BTO パソコンを使っている。 HDD や DVD ドライブは変更され、内部も色々と拡張してあるが、 4 年を過ぎたあたりから PC の調子がおかしくなった。

システムがいきなり停止する (Windows エラーログに書き込まれる前に停止) 。
この手のエラーはハードウェアなのだと思っていたのだが、5 年を突破するとログイン時にすら停止してしまうほど。
これはいよいよ PC を買い換えなきゃダメかと思って、色々と情報を集めてみると、 ( 買うときには知らなかったのだが ) ドスパラの BTO パソコン にはよろしくない話題も多々あった。

そこで、数千円で直ったらもうけものくらいの気持ちで電源を交換してみたら、それまでの不安定感が嘘のように安定してくれた。


今回交換したのは、 SILVERSTONE SST-ST50F-ES。
音も静かで、今のところ不満は全くない。次回、もし電源を買う機会があったらこれにしよう。


あまり評判の良くない EVER GREEN という電源。
5 年間で、電源を入れない日はほぼなく、一日の使用時間は 5 時間ほど。
通常の電源の耐久性がどの程度なのか、電源が壊れるまで同じ PC を使ったことがないので不明だが……。

どこが壊れたかという事実だけで語るならば、マザーボードよりも、CPU よりも、電源が先に壊れたということになる。逆に言えば、電源はけっこう重要なのだと再認識した。

ドスパラの PC 自体は、ケーブルもちゃんと固定してあたし、ケースの剛性も高そうでそんなに印象は悪くない。

でも、次も買うかと言われたら……どうだろう? (笑)

[VBA] オブジェクトが閉じている場合は、操作は許可されません。



ADO にてストアドを呼び出した際に、呼び出しは成功し、戻り値も返ってくるにもかかわらず Recordset の接続が切断されてしまうエラーに遭遇。
原因は、ストアド側で SET NOCOUNT ON; 以前に Select や Insert などの処理を行っていたためだった。

SET NOCOUNT ON; に設定すると、クライアント側に処理された行数を返却しないので、ネットワークの帯域も圧迫しないらしい。
これはクライアント側への通知設定であるので、@@ROWCOUNT 関数は更新される。

SET NOCOUNT (Transact-SQL) - msdn

[Google Chrome] 新しいタブ 画面を戻す


Chrome の新しいタブがだいぶやらかしていて驚愕した。自分の使い方だと、アプリをいくつか登録しておいたので、それらに一発でアクセスできなくなってだいぶ使い勝手が悪くなった。
そもそも、よく使うタブとかいらない。

Chromeの「おせっかい」な新しい新規タブページを以前の設定に戻す方法 - lifehacker
http://www.lifehacker.jp/2013/10/131004chrome.html
  1. アドレスバーに chrome://flags/ と入力。
  2. 設定画面から 「Instant Extended API を有効にする」 を探す。Ctrl + F で検索窓を出して、"ins" まで入力するとハイライトするはず。
  3. 「規定」 を 「無効」 に変更。
  4. Chrome の再起動。
ここ数年の Google は変更する度にどんどん使い勝手が悪くなっている気がする。

[Excel] セルの背景色を取得する

Excel にて、シートに使われている色が、テーマの色、標準の色、最近使用した色、いずれにもない場合、どのように取得するのだろうか?
背景色は以下の通り。
  1. 該当のセルを選択する。
  2. [その他の色] を選択。
  3. 色の設定ダイアログが表示され、使用されている色がわかる。

該当のセルを右クリックし、セルの書式設定から [塗りつぶし] - [その他の色] でもわかる。
文字色も同じ要領で取得することができる。

[VBA] 複数ステップの OLE DB の操作でエラーが発生しました。

VBA からストアドを呼び出した際に、以下のようなエラーが発生した。
ストアド内で使用しているテーブルやビューなどの定義が違う場合でもこのようなエラーメッセージが返ってくるようだ。

Msg = 複数ステップの OLE DB の操作でエラーが発生しました。各 OLE DB の状態の値を確認してください。作業は終了しませんでした。
Number = -2147217887
SqlState   =
Source = Microsoft OLE DB Provider for SQL Server
NativeError = 0

[SQL Server] データをランダムに抽出するための NEWID 関数と件数指定

SQL Server には、ランダムにデータを抽出したい場合などのために、NEWID() という組み込み関数が用意されている。

NEWID (Transact-SQL) - msdn
http://technet.microsoft.com/ja-jp/library/ms190348.aspx

上記の NEWID() と TOP を組み合わせることで、ランダムに指定した件数のデータを抽出する SELECT 文が完成する。
IF EXISTS (SELECT * FROM TEMPDB..SYSOBJECTS WHERE ID = OBJECT_ID('TEMPDB..#HOGE')) DROP TABLE #HOGE
CREATE TABLE #HOGE
(
 NUM  INT IDENTITY
 ,NAME  VARCHAR(20)
)
INSERT INTO
 #HOGE (NAME)
VALUES
 ('Casey ')
 ,('Katelyn')
 ,('Garrett ')
 ,('Leslie ')
 ,('Spencer')
 ,('Monique')
 ,('Martin')
 ,('Alexandria')
 ,('George')
 ,('Holly')
 ,('Manuel')
 ,('Mayra')
 ,('Marcus')
 ,('Krystal')
 ,('Mario')
 ,('Bianca')

-- TOP で件数指定することで、ランダムに取得。
SELECT
 TOP 10
 NUM
 ,NAME
FROM
 #HOGE
ORDER BY NEWID()

DROP TABLE #HOGE

[SQL Server] ランダム関数で乱数を取得

SQL Server で乱数を取得したい場合、RND() 関数を使用する。
これは 0 以上 1 未満の範囲の値を返す関数である。

Rnd 関数 - msdn
http://msdn.microsoft.com/ja-jp/library/cc410290.aspx
SELECT
 RAND() RND
 -- 乱数取得 (0 ~ 99)
 ,CONVERT(NUMERIC(2,0), RAND() * 100) RND0_99
 -- 乱数取得 (0 ~ 999)
 ,CONVERT(NUMERIC(3,0), RAND() * 1000) RND0_999

[SQL Server] スカラー関数とテーブル値関数

SQL Server にはシステム関数のほか、スカラー関数とテーブル値関数がある。
スカラー関数とは、単一のデータを返すものである。text、ntext、image、cursor、および timestamp 以外の任意のデータ型を指定でき、return でこれらの値を返却することができる。

テーブル関数とは、その名の通りテーブル値を返すもので、結果セットは table である。これはビューとストアドプロシージャーの中間のような位置づけとも言える。

関数の種類 - msdn
http://technet.microsoft.com/ja-jp/library/ms177499(v=sql.105).aspx
ビューとストアドプロシージャの強力な代替手段「ユーザー定義関数」 - japan.internet.com http://japan.internet.com/developer/20061025/27.html

[VB6, VBA] 定義されているはずの enum でコンパイルエラーが発生する。

条件は不明だが、時折「定数式が必要です」というエラーダイアログが表示されてプログラムが実行できなくなる。 普通に考えると enum が定義されていないのかな、と思うのだが、定義されていてもこのエラーが発生する場合がある。

エディタを再起動するか、enum に Private や Public などを追加してからコンパイルすると直る可能性がある。
スコープを変更して直したあとで元の状態に戻すと、なぜかエラーが解消していたりする。
単純なエディタのバグだ。

[SQL Server] datetime 型は、なぜ 1753 年が下限なのか。

SQL Server の datetime 型は、1753 年 1 月 1 日から 9999 年 12 月 31 日までの日付範囲を持つ。従って、以下のような変換はエラーとなる。
DECLARE @d DATETIME = CONVERT(DATETIME,'1752')
-- varchar データ型から datetime データ型への変換の結果、範囲外の値になりました。
では、なぜ 1753 年から開始なのか。
それは datetime 型が「グレゴリオ暦」であることに起因している。

当時のイギリス帝国 (とその植民地) でグレゴリオ暦を採用した年が 1752 年であり、
通年としてグレゴリオ暦が始まったのが 1753 年からだからである。

グレゴリオ暦 (Wikipedia)

SQL Server 2008 からは dateime2 型が導入され、この型は 「西暦 1 年 1 月 1 日から西暦 9999 年 12 月 31 日 」の範囲となる。

歴史的な背景を知るとなかなか興味深い。

[SQL Server] IN 句にパラメータを指定する (ユーザー定義テーブル型)

IN 句をパラメータで指定させたいという要望はたまにあるが、動的に SQL 文を組み立てるくらいしか対処方法がなかった。しかし、SQL Server 2008 から追加された ユーザー定義テーブル型 によって似たような動きをさせることができる。
CREATE TABLE #HOGE
(
 USER_NO INT PRIMARY KEY IDENTITY
 ,NAME VARCHAR(40)
)
INSERT INTO
 #HOGE (NAME)
VALUES
 ('John')
 ,('David')
 ,('Jeffrey')
 ,('Sarrah')
 ,('Mary')

IF TYPE_ID(N'USERLIST') IS NULL
 CREATE TYPE USERLIST AS TABLE
 (
  NUM INT
 )
 GO

-- 削除する場合は以下のように記述。
-- DROP TYPE USERLIST

DECLARE @val AS USERLIST
INSERT INTO
 @val (NUM)
VALUES
 (1)
 ,(3)
SELECT * FROM #HOGE
-- USER_NO フィールドが 1 or 3 のデータを抽出する。
SELECT * FROM #HOGE WHERE USER_NO IN (SELECT NUM FROM @val)
ただ、上記のような要望がある場合は、カンマ区切りの文字列を展開したいという場合が多いだろう。カンマ区切りのデータを展開したいのなら、以下のような関数を定義するといい。

How to split a string according to a delimiter in Ms SQL Server 2008
http://howucando.com/2013/03/21/how-to-split-a-string-according-to-a-delimiter-in-ms-sql-server-2008/

[Excel 2007] フォームを表示する

  1. Office ボタンから、Excel のオプションを開く。
  2. [基本設定] - [Excel の使用に関する基本オプション] の [開発] タブをリボンに表示するにチェックオン。
オブジェクト自体を右クリックしてプロパティを表示させれば名称などの項目を設定できる。

[SQL Server] 同じ行に対して UPDATE または DELETE が複数回試行されました。

MERGE ステートメントで、同じ行に対して UPDATE または DELETE が複数回試行されました。これは、対象の行が基になる複数の行と一致する場合に発生します。MERGE ステートメントでは対象のテーブルの同じ行で複数回 UPDATE/DELETE を実行することはできません。対象の行と一致する基になる行が 1 つだけになるように ON 句を修正するか、GROUP BY 句を使用して基になる行をグループ化してください。

ややわかりづらいエラーメッセージ。
更新元レコードが複数あり、抽出条件を追加するか、グループ化することで一対になるようにしろということらしい。

TEST1

TEST2

このようなテーブルがあった際に、以下の MERGE 文を発行するとエラーとなる。
MERGE
 TEST1
USING
 TEST2
ON (TEST1.KEY1 = TEST2.KEY1)
WHEN MATCHED THEN
 UPDATE SET TEST1.SCORE = TEST2.SCORE
WHEN NOT MATCHED THEN
 INSERT (KEY1, NAME, SCORE) VALUES (KEY1, NAME, SCORE);
TEST2 テーブルのスコアを合算してマージする場合、以下のようにグループ化する。
MERGE
 TEST1
USING
 (
  SELECT
   KEY1
   ,NAME
   ,SUM(SCORE) AS SCORE
  FROM
   TEST2
  GROUP BY
   KEY1
   ,NAME 
 ) AS TEST2
ON (TEST1.KEY1 = TEST2.KEY1)
WHEN MATCHED THEN
 UPDATE SET TEST1.SCORE = TEST2.SCORE
WHEN NOT MATCHED THEN
 INSERT (KEY1, NAME, SCORE) VALUES (KEY1, NAME, SCORE);

結果は以下の通りになる。

TEST1

[Excel VBA] 先頭にシートを追加する

Worksheets.Add Before:=Worksheets(1)
先頭にあるシートをアクティブ状態にしてからシートを追加する方法もある。
Worksheets(1).Activate
Worksheets.Add
Range("A1").Activate

[Google Chrome] アップデートは管理者によって無効になっています。

Chrome は特に意識をしなくても自動的にアップデートされる。
しかし、なんらかの理由でアップデートが無効になっている時や、逆にアップデートを自動でさせたくない場合はレジストリをいじることで設定を変更できる。

\HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Update
UpdateDefault キー
1 : 自動更新させる
0 : 自動更新しない

セキュリティ上のリスクもあるので、できれば自動更新させたいところだ。

[SQL Server] WHERE 条件内での CASE 文を使った取得項目の分岐

Transact-SQL (SQL Server) でも、WHERE 条件内で CASE 文を使用できる。単純 CASE 式、検索 CASE 式、いずれもサポートされる。
-- HAGE 列の値によって 'hogehoge' と比較する項目を分岐させる

SELECT *  FROM  HOGE
WHERE
(
 CASE HAGE
   WHEN 1 THEN AAA
   WHEN 2 THEN BBB
   ELSE  CCC
  END
) = 'hogehoge'

他の条件と AND や OR で結合もできる。
なお、括弧はなくても良いが、見通しを良くするという意味で付けたほうが丁寧だろうね。

[Management Studio] インテリセンスが表示されない場合のキャッシュ初期化

Management Studio 2008 以降では、Visual Studio のそれと同じく、入力候補 (インテリセンス) が表示されるが、これはキャッシュされているらしく、調子が悪い場合はキャッシュをクリアすれば元に戻るようだ。ちなみに、他にも以下のようなショートカットキーがある。

  • メンバの一覧 (Ctrl + J)
    何もないところで入力候補を表示。
  • パラメータヒント (Ctrl + Shift + Space)
    関数等のヒントを表示。
  • クイックヒント (Ctrl + k, Ctrl + I)
    XMLエディタ時のみ使うらしい。よくわからないw
  • 入力候補(Alt + 右)
    パラメータに入力する値の候補を表示。パラメータヒントが、パラメータの機能のヒントであるのに対し、こちらのヒントは具体的な値のヒントとなる。パラメータヒントを出しつつ、入力候補を出すことも可能。実はメンバの一覧のコマンド (Ctrl + J) でも代用できる。Ctrl + Shift + Space, Ctrl + J と押下するとどういったパラメータをセットすればいいのかわかる。
  • ローカルキャッシュの更新 (Ctrl + Shift + R)
    このコマンドを実行しても特になにか反応があるわけではないが、ちゃんと更新されている…はず。

[VBA] 配列はすでに宣言されています。

コンパイルエラー : 配列はすでに宣言されています
Dim hoge(5) as Integer
ReDim hoge(0 To 10)
上記のような書き方はできない。
なぜなら、配列の拡張を行う ReDim ステートメントは動的配列にしか使えないからだ。
Dim hoge() As Integer
ReDim Preserve hoge(0 To 10)
はじめに配列を宣言しているときにインデックスを決めてしまうと拡張できない。
なお、Preserve オプションを付けることで元の値が保持されたまま配列の拡張を行うことができる。
Preserve オプションは二次元配列等には使えないので注意する。
http://msdn.microsoft.com/ja-jp/library/w8k3cys2.aspx

[C#] int? 値型にクエッションマークをつけて null を許容。

値型の変数には null を代入できない。しかし、 何らかの理由で null をセットしたい場合に備えて、Nullable という型がある (.Net Framework 2.0 以降)。
 int? i = null;
 bool? b = null;
 string s = null;
型に「?」をつけることで、null を許容するようになる。string などの参照型ではこのような書き方はできないので注意する (そもそも参照型は初めから null を許容する)。
また、? には合体演算子という働きもあり、「??」とつなげることで null の判定を簡単に行える。

 int? i = null;
 int? j = 100;
 i = i ?? j;

  // i は 100 になる。
VB の場合は、変数名に「?」をつけるのではなく、変数名に記号をつけるらしい。

[Flickr 2013] Shortcut keys

Flickr redesigned.
Press '?' key. You can see keyboard shortcuts.


Contacts list view.

Press J : Scrol to next row.
Press K : Scroll to previous row.

(Row is ignored)
Press Space : Scroll down.
Press Shift + Space : scroll up.

Photos view.

[ Navi ]
Press -> :  Next photo.
Press -< :  Previous photo.
Press > : Move the filmstrip (to right)
Press < : Move the filmstrip (to left)
Press ] : Open the next filmstrip
Press [ : Open the previous filmstrip

[ Action ]
Press F : Add to your favorite.
Press G : Add to a group.
Press E : Add a set.
Press A : Add a gallery.
Press C : Jump to comment field.
Press T : Jump to tag field.
Press P : Jump to person field.

Keyboard shortcuts can manipulate photos quickly.

[VBA] ブレークポイントで止まらない場合の対処方法

Excel の VBA で、ブレークポイントを設定しているにも関わらずデバッグできなくなることがある。

原因は不明だが、いったん空行を挿入して保存しなおすと直る場合がある。
行数で管理されている何らかのデータが、行数を変更することで修復されるような動きだった。

[Visual Studio] ビルドエラー時の挙動を設定する。

ビルドエラーが発生しました。続行して、最後に成功したビルドを実行しますか?

ビルドに失敗すると表示されるダイアログボックスだが、今後このダイアログを表示しない。にチェックを入れると、次回以降は選択した挙動となる。
うっかりこれにチェックを入れた場合、以下の方法で再設定できる。

[ツール] - [オプション] - [プロジェクトおよびソリューション] - ビルド / 実行 → 実行時に、ビルドまたは配置のエラーが発生したとき

  • 古いバージョンを起動する (ダイアログで「はい」を選択した場合)
  • 起動しない (ダイアログで「いいえ」を選択した場合)
  • 起動時に確認する (毎回ダイアログボックスが表示される)

[C#] オブジェクトの型チェック

Object 型の型チェックは様々な方法があるが、is で判定する方法がよくとられる。
object obj = null;
if (obj is string)
{
}
// false
空文字か null かのチェックをするケースもよくするが、うっかりこう書いてしまうと危険だ。
object obj = null;
if (string.IsNullOrEmpty(obj.ToString()))
{ 
 // 例外が発生する。
}
これは null を参照してしまうケース。
ToString() の対象となる変数が null であるため、ToString() メソッドにアクセスできないためだ。

参照型であるなら、as でキャストする方法もある。
これはチェック目的というよりも、とりあえず値を変換したい場合か。
object obj = null;
string s = obj as string;
// s = null
変換できない場合、代入先の変数には null になる。

as は int などの値型には使用できない。
で、TryParse を使おうとすると、TryParse は string 型の引数しか取れないことにぶち当たる。
ToString() などとやってしまうと……例外が発生する可能性がある。ならば Convert なら。Convert ならなんとかしてくれるはずだとこう書く。
object obj = null;
int i;
if (int.TryParse(Convert.ToString(obj), out i))
{
}
Convert は変換できない場合は勝手に空文字にしてくれる。
しかし、何をやりたいのかわからなくなってくるw

結局、型のチェックをするという構造自体まず避けるべきだし、チェックをかけるなら is で。
また、キャストも色々と方法があるが、ToString() で落ちてしまうようなソースにならないよう、はじめにちゃんと考えるべきなのだろう。

[Word] 作業ファイルを作成できません。環境変数 TEMP の設定を確認してください。


そのほか、Excel の "画像が × 印になって表示されなくなる" という事象、PowerPoint の "このイメージは、現在表示できません" も同時に直す方法がようやく判明した。

もちろん、本当に環境変数がおかしい場合もあるが、結論からいうと Office と Internet Explorer は 2010 になってもなお、密接に結びついており、OS とも密着しているようだ。

こちらのサイトにあるとおりだった。
解決方法は、IE の一時ファイルの場所を変更し、ログオンし直したらきれいさっぱりすべての現象が直ってくれた。

Office 2007とInternet Explorer 7.0の密接な関係 http://xwin2.typepad.jp/xwin2weblog/2008/09/office-2007inte.html

このパターンは、TEMP や 一時ファイルを任意の場所に移動したあと、該当するドライブがなくなってしまったときに発生する。RAM ディスクを作成した場合に起こりやすいのではないだろうか。

なお、Office 2010 と IE 9 (Windows 7) などでも同様の現象が起こる。
これはいい加減 修正した方がいいと思う。

[C# 2.0] 匿名メソッドもラムダ式と同じように書ける

C# 3.0 より導入されたラムダ式により、C# のソースは劇的に変化した。
とはいえ、これは C# 2.0  にもあった匿名メソッドをより簡潔にしたものであるので C# 2.0 でも同じようなことは書ける。

2.0 世代に、積極的に匿名メソッドを書いているソースは自分は見たことがないのだが、C# 3.0 以降の書き方に慣れてしまうと 2.0 世代のソースは冗長なものに見えてしまう。

foreach の書き換え。

List< int> lst = new List< int>();
lst.Add(-10);
lst.Add(5);
lst.Add(24);
lst.Add(112);

List lst2 = lst.FindAll(delegate(int i)
{
    return i < 10;
});
lst2.ForEach(delegate(int i)
{
    Console.WriteLine(i.ToString());
});

// -10
// 5
だいぶ簡潔に書ける。
しかし、以下のようにも書けてしまう。
一見すると意味不明ではあるがエラーにはならない。
lst.FindAll(delegate(int i) { return i < 10; }).ForEach(delegate(int i) { Console.WriteLine(i.ToString()); });

値の一致

List< int> lst = new List< int>();
lst.Add(-10);
lst.Add(5);
lst.Add(24);
lst.Add(112);

bool b = lst.Exists(delegate(int i) { return i.Equals(5); });
Console.WriteLine(b);

// True

文字列の検索

List< string> lst = new List< string>();
lst.Add("taro");
lst.Add("jiro");
lst.Add("hogetaro");
lst.Add("hogejiro");

// あいまい検索。
List< string> lstLike = lst.FindAll(delegate(string s) { return s.Contains("taro"); });
lstLike.ForEach(delegate(string s)
{
    Console.WriteLine(s);
});

// taro
// hogetaro

// 厳密な文字検索。
List< string> lstTaro = lst.FindAll(delegate(string s) { return s.Equals("taro"); });
lstTaro.ForEach(delegate(string s)
{
    Console.WriteLine(s);
});

// taro
今さらだが、こんな書き方もある。
未だに 2.0 でやってるような現場も多いが、使える機会があったら試してみよう。
確かに C# 2.0 時代は foreach をとにかく多用して、条件式で判断するようなソースをゴリゴリ書いていたものだ。

[Thunderbird] アカウントの並び替えアドオン

Thunderbird はデフォルト状態ではアカウントを追加する順番で受信トレイが表示されている。
アカウント関係なくメールをチェックする用途であればアカウントの並び方など問題にならないだろうが、アカウントごとに細かく設定を分けている場合には、使用頻度によってこの並び順をソートしたいと思うだろう。

Manually sort folders は、そんな要望をシンプルに実現してくれるアドオンである。
このアドオンをインストール後に再起動し、アドオンメニューを開くとこんな感じにアカウントのソートが簡単にできる。
こういう細かい機能は本来標準でついていてほしいものだ。

金持ち父さん貧乏父さん


この本は、残念ながら……マルチ商法のバイブルと化している (笑)。
彼らは得意げに"ネットワークビジネス"と喧伝するが。

本読みますか?
最近読んでためになったのが、『金持ち父さん貧乏父さん』なんですよ。

と、言ってきたらそいつはマルチの勧誘だろう。
これを読ませて、ネットワークビジネスで不労所得を得よう!自己実現しよう!と言い始める。
それは個人の考えなので良いのだが、この本がそういう風に使われている事実は少々残念な気がする。

この本はそういう内容ではないし、不労所得を得ることが偉い、やらないやつはダメだ、という話は書いていない。
要約すると、
今いる自分の環境や世界がすべてではないよ、特にお金の世界はね
と、いうだけの話。実際には、金持ち父さん、はフィクションだという。

この本をどうとらえるかで本の評価は全く異なってくる。
個人的には、過去いろいろと出版されてきた自己啓発の本をもとに、筆者が自己の体験を元にうまく作品に昇華させている。自己啓発本だと思う。

お金、にフォーカスをあてて経済などの本だと思う人は、これに影響されて投資や不労所得ということを狙おうという考えばかりを持つため痛い目にあうのではないだろうか。

自己実現のために、なにをしたか。
なにに気をつけてきたか。
どうすれば人生が変わっていくのか。

小さな積み重ねが結果を生む、という話を実践できる人は、
結果的に「金持ち父さん」になれるのだと思う。

金持ち父さん貧乏父さん

[Firefox 20] 強化されたプライベートブラウジング機能をさらに便利にする


Firefox のプライベートブラウジング機能はいまいち使い勝手が悪かった。
ウェブブラウジング中に特定のリンクだけプライベートブラウジングで開きたいという場合でも、開いているすべてのタブがプライベートブラウジングになってしまうのだ。

Chrome では右クリックから別ウィンドウをプライベートブラウジングとして開くことができるので、
この辺りは Chrome と比較すると使いづらい部分だった。

それが Firefox 20 になり、Firefox でもようやく別ウィンドウでプライベートブラウジングできるようになった。

これだけでもだいぶ前進した感じだが、さらに Private Tab というアドオンをインストールすることで、タブごとにモードを切り替えることができるようになる。これは Chrome よりもさらに使い勝手が良い。



Private Tab
https://addons.mozilla.org/ja/firefox/addon/private-tab/

[Entity Framework] FunctionImport "" はコンテナー "" で見つかりませんでした。


例えば、"HogeProcedure" というストアドを作成して、それを Entity Framework から呼び出すとする。作成したストアドを EDM (Entity Data Model) から更新すれば、とりあえずストアドが取り込まれる。

しかし、この状態でストアドを呼び出そうとすると、以下の様なエラーが出る。

FunctionImport 'HogeProcedure' はコンテナー 'HogeDBEntities' で見つかりませんでした。


取り込んだストアドは、「モデル ブラウザー」から該当するストアドを右クリックして、関数インポートの追加を行わなければならない。これは、上に書いた取り込みを行うと、論理モデルは生成されるのだが、概念モデルとしては定義されていないため、見つからないということらしい (ややこしい話だが)。

関数インポートを複合型にマップする (Entity Data Model ツール) - msdn

[SQL] 日付条件の注意点


Transact-SQL のお話。
非常によくある要件に、現在日時から○ヶ月前のデータを取得する、一定の期間内のデータを取得する、だとかがある。
で、検索対象となるカラムが datetime で、日付を検索条件とする際には注意が必要だ。

例えば、二ヶ月前から現在のデータを取得するには……。
-- GETDATE() = 2013-03-01 20:12:13.583

SELECT * FROM Hoge WHERE PROCESS_DT between DATEADD(month, -2, GETDATE()) AND GETDATE()
とやりがちで、データも取得できるので一見良さそうにみえる。
しかし、「2013-01-01 11:11:11.111」のレコードが取得できるだろうか?
これではできない。
時間も検索条件に入ってしまっているためだ。

なので、以下のように時間をリセットしなければならない。
DECLARE @dt DATETIME

SET @dt = CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE(), 112))

SET @dt = DATEADD(month, -2, @dt)
CONVERT
http://msdn.microsoft.com/ja-jp/library/ms187928.aspx - msdn
DATEADD
http://msdn.microsoft.com/ja-jp/library/ms186819.aspx - msdn

しかし、これでも完璧ではない。
二ヶ月前の同日を含めるためには、意図的に一日進めなければならない。
SET @dt = DATEADD(DAY, 1, @dt)
この記事はいつまで経っても秀逸だ。
http://itpro.nikkeibp.co.jp/article/COLUMN/20060309/232077/ - ITPro

[Office 365] -UserPrincipalName の禁止文字


New-MsolUser などの -UserPrincipalName パラメータには使用できない文字がある。

パラメーターの値が無効です。パラメーター名: UserPrincipalName。

しかし、これでは一体どの文字が使用できないのかわからない。
試してみたところ、以下の文字は弾かれるようだ。

/ \ [ ] : ; | = , + * ? < > @ "' % & { } ( ) ^ ~ `

記号でも、「#」「$」「!」は使用できる。

[ExpressWeb] Web 発行を行う

Visual Studio の Web 発行機能を ExpressWeb で行う場合のメモ。
  1. 管理画面から設定をする。

    [Web サイト] - [管理] にて、リモート管理を有効に。
  2. Visual Studio から発行する。

    設定したユーザー名とパスワードを入力する。「サービス URL」 と 「サイト / アプリケーション」 は、発行先のドメイン名を入力する (http 等はいらない)。
    なお、「信頼されていない証明書を許可する」 チェックボックスは必ずオンにしておく。
資格情報のチェックを入れるとユーザー名とパスワードが合っていても接続できないので注意する。

[GOM Player] wmv のシークが遅い


どうにもならないようなので、VLC media player というプレイヤーを試してみたら、これなら問題なくシークできる。動作もこちらの方が軽いようだ。

[MVC 4] Visual Studio 2010 で ASP.NET MVC 4 を開発する。

Visual Studio 2012 だと標準で ASP.NET MVC 4 のプロジェクトが作れるようになっているのだが、Visual Studio 2010 (Visual Web Developer 2010 も) 向けの ASP.NET MVC 4 もある。

Visual Studio 2010 SP1 および Visual Web Developer 2010 SP1 用 ASP.NET MVC 4

はじめ JPN の方をインストールしたら、なぜか新規作成で MVC 4 が出てこなかった。
自分の環境だけなのかよくわからんが…。



[SQL Server] Transact-SQL で乱数を発生させる RAND() 関数


RAND() 関数は、0 から 1 の乱数を発生させるので、「0.123456」のような値を返す。
しかし、こういう値はあまり実用的ではないと思う。
乱数を整数に揃えるためには、結局キャストしかないようだ。

-- 出力例 : 123456
print Cast(RAND()*1000000 as varchar(max))

[C#] ConnectionStrings が取得できない。



Config ファイルに記載した接続情報を ConfigurationManager クラスの ConnectionStrings で取得する際には、呼び出し元のクラス (プロジェクト) の Config ファイルを取得する。つまり、以下の場合は、A プロジェクトにある Config ファイルを取得する。

  • A プロジェクトから B プロジェクト (DLL 等) を呼び出す。
  • B プロジェクト内で ConnectionStrings を取得させる。

しかし、Config ファイルが存在しない状態で ConfigurationManager を参照すると、ConfigurationManager は machine.config を参照する。
ここには "LocalSqlServer" や "LocalMySqlServer" などが設定されていることがあり、混乱する。
参照する条件等があるのか調べきれていないが、思い込みで調査すると間違える可能性がある。

var connectionStrings = ConfigurationManager.ConnectionStrings;
Console.WriteLine("Connection strings.");
for (var i = 0; i < connectionStrings.Count; i++)
{
  var name = connectionStrings[i].Name;
  Console.WriteLine("Name: {0} Value: {1}", name, connectionStrings[name]);
}

[AIMP3 Audio Converter] LAME エンコーダーを使って MP3 に変換する。


AIMP3 は高音質の音楽プレイヤーであるが、付属している 「AIMP3 Audio Converter」 にはライセンスの都合上、初期状態では MP3 のエンコーダーが含まれておらず、MP3 への変換はできない。

そこでフリーの MP3 エンコーダーを別途用意しようとして LAME のサイト に行ったのだが、dll を発見することはできなかった。
もう少し探してみると、RAREWARES というサイトで dll が配布されているのを発見。

解凍したフォルダの中にある lame_enc.dll を AIMP3 の Modules フォルダにコピーする。

例 )
C:\Program Files\AIMP3\Modules

AIMP3 Audio Converter を再起動すると、MP3 が変換できるようになっているはずだ。

ちなみに、MP3 の変換方式の違いは以下のように言われている。
  • VBR
    可変ビットレートで、品質のバラツキを防ぐ。ファイルサイズが同一であるなら、CBR より高音質といわれる。ただし、音ズレが発生しやすい。
  • ABR
    固定ビットレート。特に動画の場合、音ズレが発生しにくくなる。ただし、VBR と比較すると品質は劣る。
  • ABR
    VBR の一種。データ全体のビットレートを平均化する。圧縮に時間がかかる。

[Tissot] 秒針のズレは簡単に調整できる。


PRC200。いつの間にか秒針 (ストップウォッチの方) がズレていた。
別に気にならないので放置してそのままにしておいたのだが、竜頭を引いて下のボタンを押したら秒針が動いて調整できると知った。知ったからには調整してみた。
ピッチリ合っていないと気が済まない神経質な人でもこれで安心だ (笑)。

[C#] ラムダ式はデリゲート型ではないため、型 ´ ´ に変換できません。

いろいろな理由があるのだが、名前空間がない場合もこのエラーが出る場合がある。
まず、System.Linq 名前空間がインポートされているかチェックしよう。
u sing System.Linq;

また、System.Linq 名前空間は、System.Core アセンブリ (System.Core.dll) に含まれているそうだ。

System.Linq 名前空間 - msdn
http://msdn.microsoft.com/ja-jp/library/vstudio/system.linq.aspx

[C#] テキストボックスで「Ctrl + c」や「Ctrl + v」のイベントを処理する。


コピーやペーストを禁止したい場合、別の処理を追加しなければならないが、
テキストボックスのショートカットキーを拾うだけなら KeyDown イベントを追加する。
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
  if (e.KeyData == (Keys.Control | Keys.C))
  {
    // Ctrl + C
    toolStripStatusLabel1.Text = "Ctrl + C が押されました。";
  }
  else if (e.KeyData == (Keys.Control | Keys.V))
  {
    // Ctrl + V
    toolStripStatusLabel1.Text = "Ctrl + V が押されました。";
  }
}

[Windows Update] KB とは。


Windows Update でインストールされるプログラムには、頭に "KB" という記号が付いている。
KB とは、Knowledge Base のことらしい。

Microsoft のサポートで検索する方法があるのだが、
検索窓から KB 番号を入れても検索されるのは一部のものだけのように見える。

「サポート技術情報」 (Microsoft Knowledge Base) の検索方法に関するヒント | support.microsoft.com
http://support.microsoft.com/kb/242450/ja#12

[C#] List の Contains とラムダ式による検索

List の中にある値が含まれているかどうかというチェックに関しては、
List の Contains を使えば良い。

しかし、ある値に List に定義された値が含まれているか、という逆のチェックは
List(T).Contains メソッドではチェックできない (そもそも期待する結果にならない)。

これを実現するには、foreach 等でリストを回してチェックすることを思いつくのだが、
ラムダなら 1 行で済む。
 var input = " I'd like to have some orange juice.";
 var fruits = new List { "apple", "orange", "banana", };

 var result1 = fruits.Contains(input);
 Debug.WriteLine(result1);

 var result2 = fruits.Exists(w => input.Contains(w));
 Debug.WriteLine(result2);

 var result3 = false;
 foreach (var x in fruits)
 {
     if (input.Contains(x))
     {
         result3 = true;
         break;
     }
 }
 Debug.WriteLine(result3);

 // 結果
 // result1 = false
 // result2 = true
 // result3 = true

[C#] Enum の存在チェックは奥が深い。

ある値が、Enum に含まれているかどうかのチェックには色々な方法があるのだが、回すやり方が速いようだ。少々意外な結果である。
class Program
    {
        enum MyEnum { a = 0, b, c }
        private const int loop = 10000000;

        static bool IsDefined(MyEnum myEnum)
        {
            var b = false;
            switch (myEnum)
            {
                case MyEnum.a:
                case MyEnum.b:
                case MyEnum.c:
                    b = true;
                    break;
            }
            return b;
        }

        static void Main(string[] args)
        {
            var sw = new Stopwatch();

            // Enum.IsDefined
            sw.Start();
            for (int i = 0; i < loop; ++i)
            {
                Enum.IsDefined(typeof(MyEnum), 0);
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);

            // 泥臭い ? やり方
            sw.Reset();
            sw.Start();
            for (int i = 0; i < loop; ++i)
            {
                IsDefined((MyEnum)0);
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);

            // TryParse
            sw.Reset();
            sw.Start();
            for (int i = 0; i < loop; ++i)
            {
                var myEnum = new MyEnum();
                var b = Enum.TryParse("0", out myEnum);
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);

            // 強引に LINQ を使う
            sw.Reset();
            sw.Start();
            for (int i = 0; i < loop; ++i)
            {
                Enum.GetValues(typeof(MyEnum)).Cast().Contains((MyEnum)0);
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);

            /*
             * 2544
             * 126
             * 4603
             * 26415
             */

        }

    }
あとは、IsDefined のパフォーマンスが悪いという話をよく目にするが、実際はそれほど問題になるようなことはないと思う。それならソースの見通しを良くしておいた方がいいかな、というのが持論。

[C#] 内部例外とは

詳細については、内部例外を参照してください。

内部例外というのは、InnerException の事であり、
例外のさらに前で発生した例外 (つまり原因となる例外) を意味する。

内部例外が発生していない場合はこの値は null (VB の場合は Nothing) になる。

[Windows] ドラッグアンドドロップの「コピー」と「移動」の違い


Windows の仕様では、コピー元のファイルがどこにあるか、そして、ドラッグアンドドロップ先のフォルダのドライブがどこであるかによって挙動が変わる。

通常、ドラッグアンドドロップ先が同一ドライブの場合は「移動」が行われ、別ドライブの場合は「コピー」が行われる。
また、キーボードから挙動を固定することもできる。

ファイルの移動 : Shift & ドラッグアンドドロップ

ファイルのコピー : Ctrl & ドラッグアンドドロップ

Windows 7 なら、どちらの挙動になるのかツールヒントが表示され、
移動なのかコピーなのか表示されるようになっている。

[Windows 8] 英語キーボードでハマる。

Windows 8 は IME に色々と癖があるようだ。
使い始めた瞬間に困惑したw

Windows 8 では、IME のオンとオフが、システム全体で保持されているらしい。
なんという仕様……。

Windows 8のIMEのオン/オフをアプリごとに制御する - @IT
http://www.atmarkit.co.jp/ait/articles/1212/14/news050.html

日本語入力のオンとオフ - Microsoft
http://windows.microsoft.com/ja-JP/windows-8/ime-enable-help

英語キーボードの場合、
IME オン・オフは 「Alt」 & 「~」 (日本語キーボードでは半角/全角があるキー) である。


IME の種類は、「Windows キー」 + 「スペース」 で切り替えられるようになった。
これは良い。あまり切り替えないかもしれないが……。