ぺやろぐ

ぺやろぐ

焼きそばよりチャーハンが好き。

〔C#〕CSVのデータ内にカンマがあっても、カンマ区切りでデータを取得する


カンマのためのカンマによるカンマを区切る記事。
どうも、ぺやんぐです。


目的

CSVのデータ内にカンマがあっても、カンマ区切りでデータを取得することができるようになること。
TextFieldParserの存在を知ること。


経緯

とあるテーブルの値をまるまる開発環境から本番環境に移動したかったんだけど、開発環境と本番環境でDBの場所が違う。

なので、データを手動で更新する必要が出たんだけど、テーブル削除して新しく作るのはなんか怖いしってことでデータを一旦CSVに吐き出して持っていくことになった。

ただ、このままだと1個1個手動で書き換えとか嫌なので、出力したCSVからUPDATE文を作ってやろうと考えたのが今回の始まり。


作業開始

コンソールアプリでCSVからUPDATE文を書いたテキストを吐き出すプログラムを作ることになったんだけど、「データ内にカンマあるやん。普通にカンマ区切りにしたらまずいぞこれ。」と気づく俺氏。

幸いにもダブルクォーテーションでくくられてる中にあるから、そのあたりで判断させたらいけそうやなぁと検討をつけるが、どうやるんやろとグーグル先生に質問することに。

すると、まんまそれに対応したものを見つけました!(やったね!)


先人に感謝

で、見つかったのが「TextFieldParserクラス」
以下、実際のコード


TextFieldParserの使用例


TextFieldParserっていうのを使い、デリミタにカンマを指定してあげると、区切り用のカンマできれいに区切ってくれます。
あとはそれをごにょごにょするだけ。
まさか、こんな便利なものが存在するとは。
ありがたいですねぇ。


まとめ

TextFieldParserすげぇ。
あと、「タブ区切り使えや」って意見は(∩゚д゚)アーアーきこえなーい

〔C#〕 nameof演算子が使えないけど、似たようなことをする(プロパティ名の取得)

どうも、ぺやんぐ(@peyangu485)です。

nameof演算子は便利だねってお話。


◆目的

C# 5.0以下の環境でnameof演算子と似たようなものを実装する。
改めてnameof演算子っていいよねって気付く。


◆経緯

WPFの実装中、


NotifyPropertyChangedに文字列の引数


と文字列でNotifyPropertyChangedに引数を渡しています。
これ、プロパティ名を変更しても文字列は変更対象にならないので、ここの変更忘れが原因で動かなくなるってことが起きるんですよね。
まぁ、そこまで気づきにくい場所でもないのですがちょっと鬱陶しいですね。


◆登場! nameof演算子!

とか思っていると、C#6.0でnameof演算子が追加され、以下のように書くことができるようになりました。


nameof演算子


nameof(プロパティ名))
たったこれだけの記述にするだけで変更がかかるようになり、つまらないミスをなくすことができるんですね。

これは素晴らしい。

いや、ほんと。

ですが、C#6.0の環境じゃないと使えない。

会社の環境によって使えるときと使えないときがあるんですよね。

「まぁ、その時は文字列でいいんじゃない?」って思ってしまいますがあえてnameof演算子と似たようなことができるようにがんばりましょう。


◆実装

以下、コード

今回使用するメソッドの定義


プロパティ名の取得


WPFでの使用例


GetPropertyNameメソッドの呼び出し


起動時はこちら
f:id:peyangu485:20160124185218p:plain

ボタン押下で
f:id:peyangu485:20160124185223p:plain

きちんと変更通知がわたっているので、文字列が表示されていますね。


◆まとめ

さすがにnameof演算子ほど短く、とは言えないですがそこそこいいんじゃないかと。
短くしたい場合は、クラス名とメソッド名をもっと簡略化すればいいかな。

どちらでも使えるようにしておきましょー。

〔C#〕〔WPF〕アプリの2重起動を防ぐ



今回は、WPFアプリで2重起動を防ぐ方法を忘れないために書いておく。

目的

WPFアプリで2重起動を防ぐ。

実装

アプリによっては、2重起動されては困るものもあると思うので(今回まさに直面した)2重起動しないようにしてみた。

手を加えるのは、App.xaml、App.xaml.csの2つ。

App.xamlでStartup="Application_Startup" Exit="Application_Exit"を追加。

<Application x:Class="applicationname.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:applicationname"
             Startup="Application_Startup" Exit="Application_Exit">
    <Application.Resources>
    </Application.Resources>
</Application>

次にApp.xaml.csでApplication_StartupとApplication_Exitを実装。

public partial class App : Application
    {
        private void Application_Exit(object sender, ExitEventArgs e)
        {
            Mutex mutex_;
            if (Mutex.TryOpenExisting("テストアプリ", out mutex_))
            {
                mutex_.ReleaseMutex();
                mutex_.Dispose();
            }
        }

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            Mutex mutex_ = new Mutex(false, "テストアプリ");
            try
            {
                if (!mutex_.WaitOne(0, false))
                {
                    MessageBox.Show("テストアプリはすでに起動しています。", "テストアプリ", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    this.Shutdown();
                }

                var mainWindow = new MainWindow();
                mainWindow.Show();
            }
            finally
            {
                mutex_.Dispose();
            }
        }
    }

Mutexはきちんと解放しないと、次に起動ができなくなるので注意!

上のコードを入れておけば、2重起動を防ぐことができる。
メッセージボックスの表示は自由だけど。

めでたし、めでたし。


変更履歴
5/17 コード修正。

〔C#〕XMLファイルの読み込みと書き込み


どうも、ぺやんぐです。

今回は気が向いたのと備忘録も兼ねて、C#でのXMLファイルの読み込みと書き込みについて。
単純な読み書きだけだから、細かい処理とかはまたいつか。

◆目的

XMLファイルの取り扱いを学ぶ。


◆実装

まず、保存するデータを持つクラスを作成

よくあるPersonクラス


Personクラス


こんなクラスがあったとする。

まずは、XMLに書き込む処理


XMLに書き込む処理


これで、Personのリストをxmlに保存することが可能。

次に、xmlからの読み込み処理


XMLから読み込む処理


これでXMLの中身を、Personのリストで返してくれる。


◆まとめ

xmlの中身は


書き込み後のXMLの中身


こんな感じになると思われる。
Nameの「aaaaa」とAgeの「20」は保存する前にリストに入れたデータ。

コード内ではリストで保持するので、データをごにょごにょしやすい。

〔C#〕〔WPF〕閉じる時に行う処理をMVVMで追加する


「ここが詰まったよ!WPF」シリーズということで第1弾は閉じる時に行う処理の追加についてご紹介します。

第何弾までやるのかは未定です。

目的

コードビハインド側で言うところの「OnClosing()」メソッドに処理を追加することをMVVMで実装する。

経緯

閉じるタイミングで何かしたいときってOnClosingに記述すれば基本的にOKなんですが

protected override void OnClosing(CancelEventArgs e)
{
       base.OnClosing(e);

       // 何か処理追加
}

MVVM的にはこれはよろしくない。(と思っています。)

そこで、どうしようかと考えた結果が以下。(かんろくのソース流用)

実装

見た目を変更して閉じるボタンを自前で用意していることが前提条件です。
デフォルトのままの閉じるボタンに処理の追加は僕にはできませんでした。(情報求ム)
まず、ViewのコンストラクタでModelクラスのCloseActionプロパティにthis.Close()の処理を渡しておきます。

MainWindow.xaml.cs

public MainWindow()
{
     InitializeComponent();

     var mView = new ViewModel.MainViewModel();
     this.All.DataContext = mView;
     // OnClose時に処理を行いたいので、Model側で閉じられるようthis.CloseをVMに渡す。
     if(mView.Model.CloseAction == null)
           mView.Model.CloseAction = new Action(() => this.Close());
}

メソッド名はなんでもいいのですが、わかりやすくOnClosingとしておいたメソッドに、追加したい処理とCloseActionプロパティの呼び出しをします。

MainModel.cs

// 閉じる処理プロパティ

public Action CloseAction { get; set; }

public void OnClosing()
{
     // 追加したい処理
     CloseAction();
}

ViewModelではコンストラクタの中でICommandのCloseにModelクラスのOnClosingメソッドを紐づけさせます。 

MainViewModel.cs

public ICommand Close { get; private set; }

public MainViewModel() 
{

     Close = new RelayCommand(_Model.OnClosing);

}

RelayCommandはGitHubを確認してください。(
KanmusuDrop/RelayCommand.cs at master · peyangu/KanmusuDrop · GitHub
)

それができたら、xamlで閉じるボタンのCommandにCloseをBindしてあげると閉じるときに処理を挟むことができます。

<Button x:Name="CloseButton" Content="r" Style="{DynamicResource CaptionButtonStyleKey}" Command="{Binding Close}">

 

まとめ

かんろくのドロップ情報を保存する処理がまんまこの流れです。

これはこれでどうなのかと思わなくもないですけどね。

一応、コードビハインドを使わずにできたってことで良しとしましょう。

もっといい実装方法あれば教えてください<(_ _)> 

ということで、第1弾「閉じる時に行う処理をMVVMで追加する」でした。

FizzBuzz問題

ほんとにすぐできたからさっそく公開。

まず、FizzBuzz問題について

wikiより

プレイヤーは円状に座る。最初のプレイヤーは「1」と数字を発言する。次のプレイヤーは直前のプレイヤーの次の数字を発言していく。ただし、3で割り切れる場合は 「Fizz」(Bizz Buzz の場合は 「Bizz」)、5で割り切れる場合は 「Buzz」、両者で割り切れる場合は 「Fizz Buzz」 (Bizz Buzz の場合は 「Bizz Buzz」)を数の代わりに発言しなければならない。発言を間違えた者や、ためらった者は脱落となる。


というゲームをプログラムで書いたらどうなるかっていうのが今回の記事のネタ。

またもやwikiより

このゲームをコンピュータ画面に表示させるプログラムとして作成させることで、コードがかけないプログラマ志願者を見分ける手法を Jeff Atwood が FizzBuzz問題 (FizzBuzz Question)として提唱した。その提唱はインターネットの様々な場所で議論の対象になっている。


だそうです。

程度の差はあれど、動くものレベルなら作れるでしょうって思いきや、できない人がちらほらいるらしい。

問題文は
「1から100までの数をプリントするプログラムを書け。ただし3の倍数のときは数の代わりに「Fizz」と、5の倍数のときは「Buzz」とプリントし、3と5両方の倍数の場合には「FizzBuzz」とプリントすること。」
で、あとは追加で条件があったりする。

このままだとまぁ、いろいろ気になる部分はあるわけだけどもあえてスルーします。(あくまで遊びなので

で、こちらが私が書いたコード
fizz1buzz

実行結果↓
fizz1buzzcon
fizz1buzzcon2

とまぁ、こうなります。

本当に動くものレベルならこれでいけます。
少し改造したものがこちら
fizz2buzz
引数を変えれば、FizzBuzzの出力位置が変わるようにしました。
あと、出力する数字の数も。

実行結果↓
fizz2buzzcon
fizz2buzzcon2
fizz2buzzcon3

4の倍数と7の倍数で文字に変わってますね。
出力している数も120まで増えてます。

もっと、いろいろ制約つけたりあえてめんどくさい処理の仕方で書いてみたりなどなどネットを探せば出てきます。

個人的なわざわざシリーズとしてはStrategyパターン使ってみたら面白そうな、ただめんどそうな感じがしてます。

これを研修終わりの新人にさせてみると、個性が見られて楽しそうです。

最後に、コードの拙さについては遊びということで目をつぶっていただきたいです……。(久々にコード書くんだもの、ちかたないね)
ネットをさ迷って、自分の勉強不足を痛感してるので、これからに期待ってことでなにとぞ(m´・ω・`)m

じゃあの