The road to C# master trapemiya

C#を中心に、.NETの話題を取り上げます

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  170  : 記事  1  : コメント  412  : トラックバック  15

ニュース

2005年10月26日、正式にこちらで本運用を始めました。(from 引越し元)

わんくま同盟

わんくま同盟

Microsoft MVP


Visual Developer - Visual C#

記事カテゴリ

書庫

日記カテゴリ

2008年4月24日 #

「サーバ」と「サーバー」、Microsoft流の表記はどっち?
http://codezine.jp/a/article/aid/2460.aspx

いつも悩んでいるんだが、最近はサーバーと書くことの方が多い。だって、そう発音するんですもの。でも、サーバの方がかっこいい。ある種の2ちゃんのような表現なのか?

だいぶ前にCD検索システムの設計をしたことがある。例えば松田聖子。マツダセイコと書くが、マツダセーコとはあまり書かない。でも、発音はセーコが一般的だと思う。今ならどっちもヒットさせることは無理な相談ではないが、当時はそうもいかなかった。だからアーティストの登録は書き言葉で行うというルールを作らざるを得なかった。だから、読みはセイコで登録した。
日本語には書き言葉と読み言葉というゆらぎがあることを思い出した。

posted @ 13:48 | Feedback (17)

2008年4月14日 #

サーバーエクスプローラからデータベースのテーブルを開いている際に、列の値にnullを入れるショートカットがCTRL + 0であることを初めて知った。これまではNULLって打ってたんだけど、CTRL + 0の方がいいな。

クエリおよびビュー デザイナでの操作 (Visual Database Tools)
http://msdn2.microsoft.com/ja-jp/library/ms175917.aspx

 

posted @ 13:29 | Feedback (3)

2008年3月31日 #

メモ。

Windows 2003 server でクラシックASPを実行。

ログフォルダに対して、BASP21のSendMailExのログ用にIUSR_xxxxxxxx(インターネットゲストアカウント)に書き込み権限、Scripting.FilesyStemObject用にNetwork Serviceに書き込み権限を与える必要があった。

posted @ 13:54 | Feedback (0)

2008年3月28日 #

久々にVS2003のプロジェクトを改修し、セットアッププロジェクトをコンパイルすると、以下の警告が・・・

------ プロジェクト 'Setup_hoge' のビルド前の検証を始めます ------
警告 : シグニチャ 'Managed.D93ED6F5_1D53_11D4_A53C_0090278A1BB8' とのモジュールの依存関係が見つかりません。
警告 : シグニチャ 'Database_Access.BF125633_EFD6_11D3_A52F_00A0C9CA42BA' とのモジュールの依存関係が見つかりません。
------ プロジェクト 'Setup_hoge' のビルド前の検証が完了しました ------

これ、
Crystal_Database_Access2003_jpn.msmにCrystal_Database_access2003.msmへの依存関係が設定してあり、同様に、
Crystal_Managed2003_JPN.msmからCrystal_Managed2003.msmへの依存関係が設定してあり、これら2つの依存関係が見つからないと警告されているようだ。

ソリューションエクスプローラでCrystal_Database_Access2003_jpn.msmを右クリックしてModuleDependenciesを見るとDatabase_Access.BF125633_EFD6_11D3_A52F_00A0C9CA42BAなんていうのが設定してあり、そこに黄色三角の中に!が書かれたマークが付いている。おい・・・

とりあえず検索して、

CrystalReportsマージモジュールの依存関係について
http://www.microsoft.com/japan/msdn/community/gdn/ShowPost-21847.htm

を見つけた。最新のマージモジュールをダウンロードして入れ替えればいいのか。

というわけで、以下よりダウンロード。

Files And Updates
http://support.businessobjects.com/communityCS/FilesAndUpdates/cr_net_2003_mergemodules_jp.zip.asp

で、解凍して得られた

Crystal_Database_Access2003.msm
Crystal_Database_Access2003_jpn.msm
Crystal_Managed2003.msm
Crystal_Managed2003_JPN.msm
Crystal_regwiz2003.msm

を、C:\Program Files\Common Files\Merge Modulesの下にフォルダを作ってその中に入れた。
早速、VS2003でマージモジュールを追加し直した。Crystal_regwiz2003.msmを右クリックしてライセンスキーを入力するのも忘れなかった。

以上でうまくいずはず・・・だった。が、やはり同じワーニングが出る。

う・・・ん
う・・・ん
う・・・ん

で、思い立って、C:\Program Files\Common Files\Merge Modulesの下のフォルダではなく、C:\Program Files\Common Files\Merge Modulesに直接入れた。つまり、既存の
Crystal_Database_Access2003.msm
Crystal_Database_Access2003_jpn.msm
Crystal_Managed2003.msm
Crystal_Managed2003_JPN.msm
Crystal_regwiz2003.msm
と入れ替えた。

で、VS2003でマージモジュールを追加し直すと、見事に警告が消えた。
GJ!
自画自賛というか、C:\Program Files\Common Files\Merge Modulesに直接入れないといけないことを知らなかったおバカさんなのね。

 

posted @ 17:52 | Feedback (0)

2008年3月26日 #

必要に迫られてネットを漁ったんですが、ありそうで見つからない。しょうがないんで自分で考えてみました。

Regex regexPath = new Regex(@"^[a-zA-z]:(\\|\\[^\\].+[^\\]\\)$")

[a-zA-z]       アルファベットの大文字・小文字に一致。(ドライブレター)
:            ドライブレターの横のコロン
(\\|\\[^\\].+[^\\]\\)   | がorなので、まず\\の部分から。これは簡単でフォルダ区切り文字 \ を表す。
            次に\\[^\\].+[^\\]\\の部分
            \\   フォルダ区切り文字 \
            [^\\] フォルダ区切り文字じゃない
            .+  任意の文字の1回以上
            [^\\] フォルダ区切り文字じゃない
            \\   フォルダ区切り文字 \

とりあえずうまく動いてるっぽい。.+が問題だけどね。何でもマッチしちゃうから。ちゃんと書くならここをフォルダに使える文字だけに制限する必要がある。まぁ、今回はどんまいw

posted @ 17:15 | Feedback (2)

int id = 2;       //抽出条件


1.標準クエリ演算子のパターン

int total = hogeDataSet.HogeDataTable.AsEnumerable()
        .Where( r => r.Field<int>(hogeDataSet.HogeDataTable.IDColumn == id) )
        .Sum( s => s.Field<int>(hogeDataSet.HogeDataTable.KingakuColumn) );


2.クエリ式のパターン

var drk = from dr in hogeDataSet.HogeDataTable.AsEnumerable()
          where dr.ID == id
          select new
          {
              kin = dr.Field<int>(hogeDataSet.HogeDataTable.KingakuColumn),
              id = dr.Field<int>(hogeDataSet.HogeDataTable.IDColumn)
          } into s
          group s.kin by s.id into grp
          select grp.Sum(_ => _);

int total = drk.FirstOrDefault<int>()

1の標準クエリ演算子を使う方は簡単なんですが、2のクエリ式を使うパターンで悩んだ。
selectもgroupもintoを使わないとそこで終ってしまうので、SQL文のようにselectとgroupを一度に書くことはできないんじゃないかと思う。
よって、SQL文に比べるとかなりやぼったくなるけど、しょうがないのかな・・・

posted @ 11:34 | Feedback (8)

2008年3月24日 #

例えば契約期間が抽出条件で指定された期間と重なっているかどうかを調べるには、

契約期間開始日 <= 抽出期間終了日 and 契約期間終了日 >= 抽出期間開始日

というのはよく使うのですが、

(契約期間開始日と抽出期間開始日の大きい方) <= (契約期間終了日と抽出期間終了日の小さい方)

というのでも可能です。後者の方が比較の数が多く効率が悪いので考えたこともなかったのですが、メリットとしては重なっている期間を得ることができます。逆に言えば、抽出条件に指定するだけなら後者の出番はないと思うんですが、たまにwhere句で見かけます。

posted @ 14:10 | Feedback (2)

2008年3月21日 #

プロジェクトのプロパティで設定タブにある接続文字列なんですが、これをコードで変更すれば、動的に本番系とテスト系のデータベースを切り替えられるようになります。
ところがです。

if (本番系データベースを使うもんね)
   Hoge.Properties.Settings.Default.hogedbConnectionString = "本番系の接続文字列";
else
   Hoge.Properties.Settings.Default.hogedbConnectionString = "テスト系の接続文字列";

なんて書くことはできない。コンパイルエラーになってしまう。これは接続文字列のスコープは強制的にアプリケーションになり、スコープがアプリケーションなものはRead Onlyだからである。
この解決方法として、VS2005まではapp.configを書き換えてスコープをユーザーにすればよかった。

でも、VS2008ではapp.configは構造が変わったらしく、無理っぽい・・・。(本当?誰か知ってたら教えて)

困った。

で、ふと思い立って、hogedbConnectionString で右クリックして「定義へ移動」を行ってみた。

 public string hogedbConnectionString {
     get {
          return ((string)(this["hogedbConnectionString "]));
     }
}

あれ? セッターが無いだけ?

てなわけでセッターを追加。

public string hogedbConnectionString {
     get {
          return ((string)(this["hogedbConnectionString "]));
     }
     set
     {
          this["hogedbConnectionString "] = value;
      }
}

結果、これで見事にHoge.Properties.Settings.Default.hogedbConnectionString をコードから変更できるようなった。
注意としては、VS2008のデザイナをいじる度に、つまりプロジェクトのプロパティで設定タブにおける内容をいじる度にセッターが消えてしまうんで、また追加してあげなければならないということです。もっとも、消えたままだとコンパイルエラーになるんで追加し忘れることはありませんが。

もう一つ注意点。TableAdapterの内部でもHoge.Properties.Settings.Default.hogedbConnectionString が使われているわけであり、これもそのまま本番系、テスト系に切り替わるので思い通りなのですが、TableAdapterは最初にHoge.Properties.Settings.Default.hogedbConnectionString の内容を取り込むと、以降、二度と取り込みません。つまり、TableAdapterを一度でも使用した後は、接続文字列を変更できないということです。
(参考)
TableAdapterがインスタンス化されただけでは、まだ接続文字列を取り込んでいないので、接続文字列を切り替えることができます。

以上より、本番系、テスト系を切り替えるのは、アプリケーションの起動時に一度だけ行うのが良いでしょう。

posted @ 17:01 | Feedback (3)

知ってる人には当たり前なんでしょうが、私はたまたま見つけてちょっとうれしくなりました。
elseの直後にキャレットがある状態でTabキーを押すと、ぬあんと、

else
{

}

という具合に、{と}を自動生成してくれ、しかもキャレットが{と}の間の行に自動的に行ってくれます。

posted @ 15:44 | Feedback (5)

2008年3月13日 #

ストアドプロシージャ内で普通にTRY...CATCHを使用するとそこでエラーを握りつぶしてしまい、呼び出し元アプリケーションにエラーがあったことが伝わらない。
例えば以下のように書くとエラーを握りつぶしてしまう。

BEGIN TRY 
   BEGIN TRANSACTION
 
   --なんとかかんとか
 
      COMMIT TRANSACTION
END TRY
BEGIN CATCH
   ROLLBACK TRANSACTION
END CATCH

この対処方法がBooks Onlineに載っている。

Transact-SQL での TRY...CATCH の使用
http://msdn2.microsoft.com/ja-jp/library/ms179296.aspx

「TRY...CATCH での RAISERROR の指定」に書かれている。
それによると、CATCHで捕まえた後、RAISERRORを利用してエラーを再スローしなきゃいけないようだ。
で、再スローするためのストアドプロシージャの例が載っている。これを以下に引用する。

CREATE PROCEDURE usp_RethrowError AS
    -- Return if there is no error information to retrieve.
    IF ERROR_NUMBER() IS NULL
        RETURN;

    DECLARE
        @ErrorMessage    NVARCHAR(4000),
        @ErrorNumber     INT,
        @ErrorSeverity   INT,
        @ErrorState      INT,
        @ErrorLine       INT,
        @ErrorProcedure  NVARCHAR(200);

    -- Assign variables to error-handling functions that
    -- capture information for RAISERROR.
    SELECT
        @ErrorNumber = ERROR_NUMBER(),
        @ErrorSeverity = ERROR_SEVERITY(),
        @ErrorState = ERROR_STATE(),
        @ErrorLine = ERROR_LINE(),
        @ErrorProcedure = ISNULL(ERROR_PROCEDURE(), '-');

    -- Building the message string that will contain original
    -- error information.
    SELECT @ErrorMessage =
        N'Error %d, Level %d, State %d, Procedure %s, Line %d, ' +
            'Message: '+ ERROR_MESSAGE();

    -- Raise an error: msg_str parameter of RAISERROR will contain
    -- the original error information.
    RAISERROR
        (
        @ErrorMessage,
        @ErrorSeverity,
        1,              
        @ErrorNumber,    -- parameter: original error number.
        @ErrorSeverity,  -- parameter: original error severity.
        @ErrorState,     -- parameter: original error state.
        @ErrorProcedure, -- parameter: original error procedure name.
        @ErrorLine       -- parameter: original error line number.
        );

で、これを利用して以下のようにすると、ストアドプロシージャの呼び出し元アプリケーションにめでたくエラーが伝わる。

BEGIN TRY 
    BEGIN TRANSACTION
 
   --なんとかかんとか
 
    COMMIT TRANSACTION
END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION
 
    -- Call the procedure to raise the original error.
    EXEC usp_RethrowError; 
END CATCH

で、ここで疑問なのが、なぜusp_RethrowErrorなんていうストアドプロシージャをわざわざ作らなきゃならないのだろう?
最初からRETHROWERRORなんていうステートメントを用意しといてくれたらいいのに。

posted @ 16:11 | Feedback (3)