goo blog サービス終了のお知らせ 

Visual C# 2005で仕事しよう

Visual C# 2005 を使って小売業で 使えるプログラムを作成する

MFC VC++6.0 で仕事しよう!No.23

2005年03月16日 15時09分33秒 | Weblog
 ダイアログベースの基本形が完成したので、今回のプログラムに合うように変えていきます。

「条件をどのように入力するか」を考えていきます。次のような例を使います。

7600053 高松市 田町 0001
7618044 高松市 円座町 0017
7618053 高松市 西ハゼ町 0037
7618026 高松市 鬼無町 0088
7618075 高松市 多肥下町 0138



このデータから「7618075」を抽出する場合、条件は「ゼロ番目が”7618075”と 等しい」です。
これを、今回はカンマを使って、次のように表現します。「0,=,7618075」です。


また、0番目が「7618050」から「7618099」を抽出する場合、次のように表現します。
「0,>,7618050,0,<,7618099」です。


さらに、「7610000」以上で、3番目が「0020」以下の場合、次のように表現します。
「0,>,7610000,3,<,00200」


またはの場合は、「-」を使って次のように表現します。
「-0,<,7618050,3,=,0138」


これで、条件の設定方法が決まりました。後は、動かして覚えてください。


条件の設定方法が決まったので、後は勢いで宣言するだけです。


ダイアログクラスにメンバ変数を追加します。

名前 説明
int m_iKeypos[ 8 ] 何番目か指定します。
CString m_sKub[ 8 ] 符号を指定します。
CString m_sKey[ 8 ] 値を指定します。
int m_iAnd アンドかオアを指定します。
int m_iKeymax 項目数の最大値



ここまでで、変数の宣言が終わりです。

次に、ウィザードを使って関数を追加します。ボタンは、もちろんクリックです。


PreTranslateMessage
OnBreenter
OnBstart
OnOK
OnCancel



ここまで、追加したらリビルドして実行です。



今回は、まだまだ行きます。

続いて、メンバ関数を追加していきます。アクセス制御はすべて「public」です。

名前
void UsParaSet()
void UsParaChk()
void UsMain()
void UsEndChk()
void UsSetMsg( int i, CString s )



ここで、リビルドして実行です。


さらに、進みます。

「PreTranslateMessage」、「OnOK」、「OnCancel」、「UsSetMsg( int i, CString s )」はまったく同じなので、前のをコピーしてください。

ダイアログクラスの「OnInitDialog」に
// TODO: 特別な初期化を行う時はこの場所に追加してください。
UsParaSet();
UpdateData( FALSE );
return TRUE; // TRUE を返すとコントロールに設定したフォーカスは失われません。
と2行追加します。


UsParaSet、OnBstartは項目抽出のをコピーして修正します。


ここまで、きたらリビルドして実行です。

今日は、ここまでです。

MFC VC++6.0 で仕事しよう!No.22

2005年03月16日 09時43分16秒 | Weblog
条件抽出プログラムのフォーム完成しましたか?前回書き忘れていましたが、アクティブな構成の設定は リリース にしてくださいね。

それでは、続けます。


さっそく、クラスを追加します。CDivTieクラスとCSysoutクラスのことです。

データをカンマで区切ってばらばらにしてくれるCDivTieクラスと操作のログを残してくれるCSysoutクラスは、とてもよく使います。クラスの中で使う変数名や関数名を覚えるとプログラムを作成するスピードが上がりますので皆さん挑戦してください。

前回から、作成方法を覚えた表で書いておきます。

CDivTieクラスのまとめ

種類 型式 名前 アクセス制御
メンバ変数 int m_iItem private
メンバ変数 CString m_sItem[ 256 ] public
メンバ関数 int DivItem( CString s ) public
メンバ関数 CString TieItem public




CSysoutクラスのまとめ

種類 型式 名前 アクセス制御
メンバ変数 int m_iMsg private
メンバ変数 CString m_sMsg[ 256 ] public
メンバ変数 CTime tm public
メンバ関数 void SysSet( CString s ) public
メンバ関数 void SysWrite public




一通り、宣言し終わったら前回作成したプログラムからコピーしてください。


その後、ダイアログクラスにそれぞれ宣言します。

種類 型式 名前 アクセス制御
メンバ変数 CDivTie dt public
メンバ変数 CSysout so public


さらに、CWnd * m_pCurpos、m_iErr、m_iDisp を宣言します。

種類 型式 名前 アクセス制御
メンバ変数 CWnd * m_pCurpos public
メンバ変数 int m_iErr public
メンバ変数 int m_iDisp public



リビルドして実行してください。ここまでが、たいていの場合必ず作成するものです。

今後、本格的に仕事(基幹業務など)に使用する場合データの並べ替えやデータ内の計算、データの縦計算など様々なプログラムが必要になります。しかし、どのプログラムもここまでが基本になっております。


今日は、ここまでです。

MFC VC++6.0 で仕事しよう!No.21

2005年03月15日 11時45分59秒 | Weblog
前回で、データの中の ” を削除するプログラムが完成しました。

それでは、条件項目抽出プログラムを作成しましょう。


条件項目抽出とは、みなさんがダウンロードした郵便番号ファイル(KEN_ALL.txt)を例に説明します。

例えば、香川県のデータを取り出したいとき

香川県は 7600000 以上 7619999 以下 という条件がわかると、抽出できます。

また、香川県高松市円座町 は 7618044 と 等しい という条件がわかると、抽出できます。

上記のような、条件項目抽出プログラムを作成します。



ダイアログベースでプロジェクトを作成します。MVC503

Input F、Include F、Omit F、Keys を 配置し それぞれの件数表示も配置します。
それぞれIDC_EINPUTF、IDC_EINCLUDEF、IDC_EOMITF、IDC_EKEYSです。

タイトル も 忘れずに。タブオーダーも1:InputF、2:IncludeF、3:OmitF、4:開始ボタン、5:再入力ボタン、6:OKボタン、7:キャンセルボタンです。


メンバ変数も追加してくださいね。


わからない人は、MFC VC++6.0 で仕事しよう!No.3を参考にしてください。

スタティック まとめの表

スタティック キャプション
IDC_STITLE < 条件項目抽出 Max 8  MVC503 >
IDC_SINPUTF Input F
IDC_SINCLUDEF Include F
IDC_SOMITF omit F
IDC_SKEYS Keys
IDC_SINPUTD Input 件数
IDC_SINCLUDD Include 件数
IDC_SOMITD Omit 件数
IDC_SMSG 処理経過


エディット まとめの表

エディット メンバ変数
IDC_EINPUTF m_sMinputF
IDC_EINCLUDEF m_sMincludeF
IDC_EOMITF m_sMomitF
IDC_EKEYS m_sMkeys
IDC_EINPUTD m_sMinputD
IDC_EINCLUDD m_sMincluded
IDC_EOMITD m_sMomitD
IDC_EMSG m_sMmsg



ボタン まとめの表

ID キャプション
IDC_BSTART < 開 始 >
IDC_BREENTER 再 入力





今日は、ここまでです。

MFC VC++6.0 で仕事しよう!No.20

2005年03月08日 14時40分46秒 | Weblog
 ダイアログ表示されましたか? タブオーダーも忘れずに指定してくださいね。

InputF、OutputF、<開始>、再入力、OK、Cancel の 順に 1、2、3、4、5、6 です。

それでは、 さっそく 進めましょう。

まずは、クラスの作成

 CDivTieクラス、CSysoutクラス を 作ります。

 中身は、以前作成した MVC501 と同じです。 メンバ関数、メンバ変数を宣言して、コピーしてOKです。



次に、CMVC502Dlgクラスに

 CDivTie:dt、CSysout:so を メンバ変数で 宣言します。



同じく、CMVC502Dlgクラスに

 int:m_iDisp、int:m_iErr を メンバ変数で 宣言します。

続いて、ウィザードを使って、OnBstart、OnBreenter、OnOK、OnCancelを作ります。

さらに、ウィザードを使って、PreTranslateMessage を作ります。

OnBstart、OnBreenter、OnOK、OnCancel、PreTranslateMessage とも 前のをコピーしてください。

  OnBstart は UsSetMsg( IDC_SITEMPOS, m_sMitempos ); を消してください。


ユーザ作成関数を 追加します。
void:UaParaSet()、void:UsParaChk()、void:UsMain()、void:UsEndChk()、void:UsSetMsg( int idc, CString s )


これらの関数も 前のを コピーしてください。



修正箇所

  UsParaSet() 

1.m_sMitempos = ""; 削除

2.if ( iitem > 4 )  4 -> 3 に変更
  {
    iitem = 4;
  }

3.case 4:
   m_sMitempos = dt.m_sItem[ 3 ];  削除
   m_sMitempos.TrimLeft( '"' );
   m_sMitempos.TrimRight( '"' );



  UsParaChk

1.InputFとOutputFの 分だけ 残す。



UsMain()は 次の通りです。


void CMVC501Dlg::UsMain()
{
  int icount, iindata, ioutdata, i, ilen;
  CString sbuf, sbuf2, sCR, swk1, swk2;
  BOOL success;
  CStdioFile inputf, outputf;
  CFileException fex;
  sCR = 0x0a;
  if ( !inputf.Open( m_sMinputF, CFile::modeRead, &fex ) )
  {
    m_sMmsg.Format( "inputf.Open Error = %s : cause = %d", m_sMinputF, fex.m_cause );
    AfxMessageBox( m_sMmsg );
    return;
  }
  if ( !outputf.Open( m_sMoutputF, CFile::modeCreate | CFile::modeWrite, &fex ) )
  {
    m_sMmsg.Format( "outputf.Open Error = %s : cause = %d ", m_sMoutputF, fex.m_cause );
    AfxMessageBox( m_sMmsg );
    return;
  }
  iindata = 0;
  ioutdata = 0;
  while( 1 )
  {
    success = inputf.ReadString( sbuf );
    if ( success == NULL || success == FALSE )
    {
      break;
    }
    iindata++;
    ilen = sbuf.GetLength();
    swk2 = "";
    for ( i = 0; i < ilen; i++ )
    {
      swk1 = sbuf.Left( 1 );
      if ( swk1 != '"' )
      {
        swk2 = swk2 + swk1;
      }
      sbuf.Delete( 0 );
    }
    sbuf2 = "";
    sbuf2 = swk2 + sCR;
    outputf.WriteString( sbuf2 );
    ioutdata++;
    icount = iindata % 10000;
    if ( icount == 0 )
    {
      m_sMinputD.Format( "%d", iindata );
      m_sMoutputD.Format( "%d", ioutdata );
      SetDlgItemText( IDC_EINPUTD, m_sMinputD );
      SetDlgItemText( IDC_EOUTPUTD, m_sMoutputD );
      UpdateWindow();
    }
  }   // while( 1 )
  inputf.Close();
  outputf.Close();
  m_sMinputD.Format( "%d", iindata );
  m_sMoutputD.Format( "%d", ioutdata );
  SetDlgItemText( IDC_EINPUTD, m_sMinputD );
  SetDlgItemText( IDC_EOUTPUTD, m_sMoutputD );
  UsSetMsg( IDC_SINPUTD, m_sMinputD );
  UsSetMsg( IDC_SOUTPUTD, m_sMoutputD );
}



最後に、セットフォーカスの関数を2つ InputF と OutputF 追加して、もちろん中身コピーして、OutputFのセットフォーカスの関数を OnBstart を 追加します。

リビルドして 実行です。

ダブルクォーテーション削除 アプリケーションの 完成です。

ダウンロードはこちら

MFC VC++6.0 で仕事しよう!No.19

2005年03月07日 09時37分46秒 | Weblog
 今、扱っているデータは データの区切りをカンマで 区切っている いわゆるCSV形式というやつです。
 このデータの中に ” があると じゃまなので これを除外するプログラムを作ります。


 ダイアログベースで 作成します。 プロジェクト名は MVC502

 ダイアログの構成

スタティック: IDC_SINPUTF、IDC_SOUTPUTF、IDC_SINPUTD、IDC_SOUTPUTD、IDC_SMSG

エディットボックス: IDC_EINPUTF、IDC_EOUTPUTF、IDC_EINPUTD、IDC_EOUTPUTD、IDC_EMSG

ボタン:IDC_BSTART、IDC_BREENTER

メンバ変数:m_sMinputF、m_sMoutputF、m_sMmsg、

忘れてました。m_sMinputD、m_sMoutputDもいります。


タイトルと日付も 変更してくださいね。

アクティブな構成の設定 も Release に 変更してください。

リビルドして 実行です。

 今回の、画像とだいたい同じのができたら OK です。

MFC VC++6.0 で仕事しよう!No.18

2005年03月04日 14時47分41秒 | Weblog
 項目抽出プログラム  みなさん できましたか? ちゃんと、動きましたか?


今日は、おさらい を やります。


項目抽出 プログラムが 起動されたとき、 OnInitDialog() が動きます。
これが 動くということは、自分で追加した UsParaSet() が動くということです。
UsParaSet() は 何をやるかというと、m_iErr と m_iDisp に 初期値を入れて メンバ変数の中身をからっぽにしています。その後、
swk = AfxGetApp()->m_lpCmdLine;
で、パラメータを swk に入れています。それから
iitem = dt.DivItem( swk );
で、パラメータをカンマでばらばらにして、それぞれのメンバ変数に入れてやります。これで、UsParaSet()は終わり。再び、OnInitDialog()に戻り、UpdateData( FALSE );を実行します。
これは、メンバ変数に入っている値をそれぞれエディットボックスに表示してくれる命令です。


次に、タブインデックスが 1 に設定してある Input F の セットフォーカスが動きます。
m_sMinputFが空っぽじゃなくて、m_iDispが0だったら 次のエディットボックスに行きなさい。
と書いてあります。次というのはタブインデックスが 2 の Output F です。
そこでも、同じように次にまわされて 最後、抽出位置 で OnBstart() が 動きます。

OnBstart() で パラメータのチェックを行い 何番目を抽出するか m_iPos[ 256 ] に入れます。
そして、UsMain()関数で 1レコードずつ処理を行い、1レコードずつ書き込みします。

全部処理すると UsEndChk() で 正常に終わってるか確認して(m_iErr=0) OnOKで 閉じます。



これが、 項目抽出プログラムの 流れです。



勘がよい人は、気づいたかもしれません。 そうです。 UsMainの中身を変化させれば 後は だいたい編集するだけで いろいろなプログラムが作れるということです。



例えば、条件抽出プログラムであれば、OutputFが2つ(条件に合うのと、合わないのと)に変えてやれば UsParaSet UsParaChk OnBstart は 編集するだけで OK です。 UsMain も 中身をちょこっとかえればできますよね。




ちょっと、話が大きすぎたかもしれません。 でも、大丈夫。


次回は、条件抽出プログラムを作成する前に 1つ 簡単なプログラムを 作ります。


今回は ここまでです。

MFC VC++6.0 で仕事しよう!No.17

2005年03月02日 09時48分04秒 | Weblog
No.16で、とうとう項目抽出プログラムが完成しました。 アプリケーションを ヤフーのブリーフケースに入れておりますので、使ってみてください。MVC501.exeダウンロードはこちら


それから、ソースファイルが 必要な方 同じく ヤフーのブリーフケース に 入れておきます。 ただし、UsMain()関数 が このブログに書いてある内容と ちょっと違います。

問題です
現状のUsMain()関数では、インプットファイルの項目数を超えた抽出位置の場合、変なデータになります。

それを、回避しています。 よかったら 考えてみてください。

 ヒント:UsMain関数の ix が iitem を 超えてないときに 項目抽出すれば OK


MFC VC++6.0 で仕事しよう!No.16

2005年03月01日 10時40分47秒 | Weblog
 なんとなく、暖かくなってきたような気がします。今日から3月です。項目抽出プログラムもとうとう完成しそうな予感がします。

 前回までで、アプリケーションをバッチファイルを使って起動して 処理させて 終了させる ことができるようになりました。仕事で使えるようにするには もうひとつ機能が 必要です。

 今回は、このプログラムの最後の機能 ログを残す を やります。




新規クラス CSysoutクラスを 作成します。

ClassViewタブをクリック -> MVC501 クラス の上で 右クリック -> クラスの新規作成

クラスの種類:Genericクラス
クラス名:CSysout

で OK を クリック

CSysout クラス が 作成されます。



この CSysoutクラスに メンバ変数とメンバ関数を追加します。


この3つの メンバ変数 を追加します。

変数のタイプ:int
変数名:m_iMsg
アクセス制御:private


変数のタイプ:CString
変数名:m_sMsg[ 256 ]
アクセス制御:public


変数のタイプ:CTime
変数名:tm
アクセス制御:public


メンバ関数 を追加します。

関数の型:void
関数の宣言:SysSet( CString s )
アクセス制御:public


関数の型:void
関数の宣言:SysWrite
アクセス制御:public



変数と関数を追加できたら 一気に書き上げましょう。

CSysout::CSysout()
{
  int i;
  for ( i = 0; i < 256; i++ )
  {
    m_sMsg[ i ] = "";
  }
  m_iMsg = 0;
}

CSysout::~CSysout()
{

}

void CSysout::SysSet(CString s)
{
  CString swk;
  tm = CTime::GetCurrentTime();
  swk = tm.Format( "[ %y/%m/%d ] %H: %M: %S: " );
  m_sMsg[ m_iMsg ] = swk + s;
  m_iMsg++;
  if ( m_iMsg >= 256 )
  {
    SysWrite();
  }
}

void CSysout::SysWrite()
{
  CString sbuf, sCR;
  int i;
  CStdioFile sysoutf;
  CFileException fex;
  sCR = 0x0a;
  if ( !sysoutf.Open( "sysout.txt", CFile::modeCreate | CFile::modeWrite | CFile::modeNoTruncate | CFile::shareDenyNone, &fex ) )
  {
    AfxMessageBox( "Open Error sysout.txt", MB_OK );
    return;
  }
  sysoutf.SeekToEnd();
  for ( i = 0; i < m_iMsg; i++ )
  {
    sbuf = m_sMsg[ i ] + sCR;
    sysoutf.WriteString( sbuf );
    m_sMsg[ i ] = "";
  }
  sysoutf.Flush();
  sysoutf.Close();
  m_iMsg = 0;
}



CSysoutクラスを CMVC501Dlgクラスで 使えるようにします。

メンバ変数を追加します。


変数のタイプ:CSysout
変数名:so
アクセス制御:public



メンバ関数を追加します。


関数の型:void
関数の宣言:UsSetMsg( int i, CString s )
アクセス制御:public


UsSetMsg関数を 次のように書きます。

void CMVC501Dlg::UsSetMsg(int i, CString s)
{
  CString swk, swk1;
  int iwk;
  iwk = GetDlgItemText( i, swk1 );
  swk.Format( "%-16s", swk1 );
  swk = swk + s;
  so.SysSet( swk );
}



OnBstart関数を 次のように 書きます。


void CMVC501Dlg::OnBstart()
{
  // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
  CString swk;
  int iwk;
  UpdateData( TRUE );
  UsParaChk();
  if ( m_iErr != 0 )
  {
    AfxMessageBox( m_sMmsg );
    return;
  }
  iwk = GetDlgItemText( IDC_STITLE, swk );
  so.SysSet( swk );
  UsSetMsg( IDC_SINPUTF, m_sMinputF );
  UsSetMsg( IDC_SOUTPUTF, m_sMoutputF );
  UsSetMsg( IDC_SITEMPOS, m_sMitempos );
  m_sMmsg = "メイン処理 開始";
  SetDlgItemText( IDC_EMSG, m_sMmsg );
  m_pCurpos = GetDlgItem( IDC_EMSG );
  GotoDlgCtrl( m_pCurpos );
  UsMain();
  UsEndChk();
}



最後に、UsMain関数も 最後の2行追加します。

void CMVC501Dlg::UsMain()
{
  int   icount, iitem, iindata, ioutdata, i, ix, ilen;
  CString sbuf, sbuf2, sCR ,swk;
  BOOL      success;
  CStdioFile   inputf, outputf;
  CFileException fex;
  sCR = 0x0a;
  if ( !inputf.Open( m_sMinputF, CFile::modeRead, &fex ) )
  {
    m_sMmsg.Format( "inputf.Open Error = %s : cause = %d", m_sMinputF, fex.m_cause );
    AfxMessageBox( m_sMmsg );
    return;
  }
  if ( !outputf.Open( m_sMoutputF, CFile::modeCreate | CFile::modeWrite, &fex ) )
  {
    m_sMmsg.Format( "outputf.Open Error = %s : cause = %d", m_sMoutputF, fex.m_cause );
    AfxMessageBox( m_sMmsg );
    return;
  }
  iindata = 0;
  ioutdata = 0;
  while( 1 )
  {
    success = inputf.ReadString( sbuf );
    if ( success == NULL || success == FALSE )
    {
      break;
    }
    iindata++;
    iitem = dt.DivItem( sbuf );
    swk = "";
    for ( i = 0 ; i < m_iMaxpos; i++ )
    {
      ix = m_iPos[ i ];
      swk = swk + dt.m_sItem[ ix ] + ',';
    }
    ilen = swk.GetLength();
    swk.Delete( ilen - 1 );
    sbuf2 = "";
    sbuf2 = swk + sCR;
    outputf.WriteString( sbuf2 );
    ioutdata++;
    icount = iindata % 10000;
    if ( icount == 0 )
    {
      m_sMinputD.Format( "%d", iindata );
      m_sMoutputD.Format( "%d", ioutdata );
      SetDlgItemText( IDC_EINPUTD, m_sMinputD );
      SetDlgItemText( IDC_EOUTPUTD, m_sMoutputD );
      UpdateWindow();
    }
  } // while( 1 )
  inputf.Close();
  outputf.Close();
  m_sMinputD.Format( "%d", iindata );
  m_sMoutputD.Format( "%d", ioutdata );
  SetDlgItemText( IDC_EINPUTD, m_sMinputD );
  SetDlgItemText( IDC_EOUTPUTD, m_sMoutputD );
  UsSetMsg( IDC_SINPUTD, m_sMinputD );
  UsSetMsg( IDC_SOUTPUTD, m_sMoutputD );
}



さあ、リビルドして 前回デスクトップ上に作成した バッチファイルを ダブルクリックです。

処理が終了したら、デスクトップ上に sysout.txt が 作成されたら OK です。

中身を見てください。 しっかりと ログが 残っているはずです。


これで、ようやく仕事につかえます。


エグゼファイルが必要な方はこちらからどうぞ。Yahoo JAPAN のブリーフケースから MVC501.exe をダウンロードしていただくことになります。
ダウンロードはこちら


今回は ここまでです。




すみません。 ひとつ書き忘れてました。

UsEndChk関数も 変更します。2行 追加して やってください。


void CMVC501Dlg::UsEndChk()
{
  if ( m_iErr == 0 )
  {
    m_sMmsg.Empty();
    m_sMmsg = "<< 正常 終了 >>";
  }
  so.SysSet( m_sMmsg );//追加です
  so.SysWrite();//追加です
  if ( m_iErr == 0 && m_iDisp == 0 )
  {
    OnOK();
  }
  UpdateData( FALSE );
  if ( m_iErr == 0 )
  {
    m_pCurpos = GetDlgItem( IDOK );
  }
  else
  {
    m_pCurpos = GetDlgItem( IDC_EMSG );
  }
  GotoDlgCtrl( m_pCurpos );
}

MFC VC++6.0 で仕事しよう!No.15

2005年02月28日 10時30分59秒 | Weblog
今日で 2月も終わりですね。 もうすぐ 春がやってきます。

この、項目抽出 アプリケーション も とうとう前回までで 項目抽出して別ファイルに保存することができるようになりました。

でも、まだ完成ではありません。 今回は、自動起動機能を追加します。


メンバ関数 を 2つ 追加します。

void UsParaSet()
void UsEndChk()


メンバ変数 を 1つ 追加します。

int m_iDisp


クラスウィザード から 関数を 3つ 追加します。

オブジェクトID IDC_EINPUTF、IDC_EOUTPUTF、IDC_EITEMPOS の 3つに

メッセージ:EN_SETFOCUS

を 追加します。

void CMVC501Dlg::OnSetfocusEinputf()
{
  // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください

}

このようなのが 3つ できたら OK です。




次のように 書きます。


void CMVC501Dlg::UsParaSet()
{
  CString swk;
  int iitem;
  m_iErr = 0;
  m_iDisp =1;
  m_sMinputF = "";
  m_sMoutputF = "";
  m_sMitempos = "";
  swk = AfxGetApp()->m_lpCmdLine;
  swk.TrimRight();
  iitem = dt.DivItem( swk );
  if ( iitem > 4 )
  {
    iitem = 4;
  }
  switch( iitem )
  {
    case 4:
      m_sMitempos = dt.m_sItem[ 3 ];
      m_sMitempos.TrimLeft( '"' );
      m_sMitempos.TrimRight( '"' );
    case 3:
      m_sMoutputF = dt.m_sItem[ 2 ];
      m_sMoutputF.TrimLeft( '"' );
      m_sMoutputF.TrimRight( '"' );
    case 2:
      m_sMinputF = dt.m_sItem[ 1 ];
      m_sMinputF.TrimLeft( '"' );
      m_sMinputF.TrimRight( '"' );
    case 1:
      m_iDisp = atoi( dt.m_sItem[ 0 ] );
    default:
      break;
  } // switch( iitem )
}



さらに、OnInitDialog も 2行 だけ 追加します。

// TODO: 特別な初期化を行う時はこの場所に追加してください。の下。



BOOL CMVC501Dlg::OnInitDialog()
{
  CDialog::OnInitDialog();
  // "バージョン情報..." メニュー項目をシステム メニューへ追加します。
  // IDM_ABOUTBOX はコマンド メニューの範囲でなければなりません。
  ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  ASSERT(IDM_ABOUTBOX <0xF000);   if (pSysMenu != NULL)
  {
    CString strAboutMenu;
    strAboutMenu.LoadString(IDS_ABOUTBOX);
    if (!strAboutMenu.IsEmpty())
    {
      pSysMenu->AppendMenu(MF_SEPARATOR);
      pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    }
  }
  // このダイアログ用のアイコンを設定します。フレームワークはアプリケーションのメイン
  // ウィンドウがダイアログでない時は自動的に設定しません。
  SetIcon(m_hIcon, TRUE); // 大きいアイコンを設定
  SetIcon(m_hIcon, FALSE); // 小さいアイコンを設定

  // TODO: 特別な初期化を行う時はこの場所に追加してください。



  UsParaSet();

  UpdateData( FALSE );



  return TRUE; // TRUE を返すとコントロールに設定したフォーカスは失われません。
}




さらに、さらに OnCancel と OnOK も 書きます。

void CMVC501Dlg::OnCancel()
{
  // TODO: この位置に特別な後処理を追加してください。
  exit( 1 );
  CDialog::OnCancel();
}

void CMVC501Dlg::OnOK()
{
  // TODO: この位置にその他の検証用のコードを追加してください
  if ( m_iErr == 0 )
  {
    exit( 0 );
  }
  else
  {
    exit( 1 );
  }
  CDialog::OnOK();
}




疲れてきました?  ちょっと 休憩しながらでいいですよ。  




続いて、 OnBstartも 次のように 書きます

void CMVC501Dlg::OnBstart()
{
  // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
  UpdateData( TRUE );
  UsParaChk();
  if ( m_iErr != 0 )
  {
    AfxMessageBox( m_sMmsg );
    return;
  }
  m_sMmsg = "メイン処理 開始";
  SetDlgItemText( IDC_EMSG, m_sMmsg );
  m_pCurpos = GetDlgItem( IDC_EMSG );
  GotoDlgCtrl( m_pCurpos );
  UsMain();
  m_sMmsg.Format( "読み込み 書き込み 終了です。", m_sMinputF );
  SetDlgItemText( IDC_EMSG, m_sMmsg );
  UsEndChk();
}




そして、そして UsEndChk を こう書きます。

void CMVC501Dlg::UsEndChk()
{
  if ( m_iErr == 0 )
  {
    m_sMmsg.Empty();
    m_sMmsg = "<< 正常 終了 >>";
  }
  if ( m_iErr == 0 && m_iDisp == 0 )
  {
    OnOK();
  }
  UpdateData( FALSE );
  if ( m_iErr == 0 )
  {
    m_pCurpos = GetDlgItem( IDOK );
  }
  else
  {
    m_pCurpos = GetDlgItem( IDC_EMSG );
  }
  GotoDlgCtrl( m_pCurpos );
}



最後に、 セットフォーカス 3つ まとめて

void CMVC501Dlg::OnSetfocusEinputf()
{
  // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
  UpdateData( TRUE );
  if ( m_sMinputF != "" && m_iDisp == 0 )
  {
    ShowWindow( SW_SHOW );
    UpdateWindow();
    NextDlgCtrl();
  }
}

void CMVC501Dlg::OnSetfocusEoutputf()
{
  // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
  UpdateData( TRUE );
  if ( m_sMoutputF != "" && m_iDisp == 0 )
  {
    NextDlgCtrl();
  }
}

void CMVC501Dlg::OnSetfocusEitempos()
{
  // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
  UpdateData( TRUE );
  if ( m_sMitempos != "" && m_iDisp == 0 )
  {
    NextDlgCtrl();
    OnBstart();
  }
}



お疲れ様でした。 リビルドして ください。


そして、 メモ帳を 起動して

皆さんの 環境に合わせて 次のように 書きます。

アプリケーションのフルパス 1,InputFフルパス,OutputFフルパス,"抽出項目"

私の場合 こうです

e:/sample/mvc501/release/mvc501.exe 1,e:/sample/ken_all/ken_all.txt,e:/sample/k01.txt,"0,1,2"

これで メモ帳に名前をつけて デスクトップに保存します。

 job.bat

デスクトップ上に ギアのようなアイコンができるはずです。

それを ダブルクリック!

<開始> クリックすると 項目抽出が 始まります。


ここで、 job.bat を 右クリックして 編集 で 1 を 0 に変えてから ダブルクリック!

自動起動 後  終了するはずです。


今日は ここまで です。


MFC VC++6.0 で仕事しよう!No.14

2005年02月25日 10時25分05秒 | Weblog
今回は、項目を抽出するところをやります。

やっと、アプリケーションらしく なってきます。


UsMain()関数を 次のように 書きかえます。


void CMVC501Dlg::UsMain()
{
  int   icount, iitem, iindata, ioutdata, i, ix, ilen;
  CString sbuf, sbuf2, sCR ,swk;
  BOOL      success;
  CStdioFile   inputf, outputf;
  CFileException fex;
  sCR = 0x0a;
  if ( !inputf.Open( m_sMinputF, CFile::modeRead, &fex ) )
  {
    m_sMmsg.Format( "inputf.Open Error = %s : cause = %d", m_sMinputF, fex.m_cause );
    AfxMessageBox( m_sMmsg );
    return;
  }
  if ( !outputf.Open( m_sMoutputF, CFile::modeCreate | CFile::modeWrite, &fex ) )
  {
    m_sMmsg.Format( "outputf.Open Error = %s : cause = %d", m_sMoutputF, fex.m_cause );
    AfxMessageBox( m_sMmsg );
    return;
  }
  iindata = 0;
  ioutdata = 0;
  while( 1 )
  {
    success = inputf.ReadString( sbuf );
    if ( success == NULL || success == FALSE )
    {
      break;
    }
    iindata++;
    iitem = dt.DivItem( sbuf );
    swk = "";
    for ( i = 0 ; i < m_iMaxpos; i++ )
    {
      ix = m_iPos[ i ];
      swk = swk + dt.m_sItem[ ix ] + ',';
    }
    ilen = swk.GetLength();
    swk.Delete( ilen - 1 );
    sbuf2 = "";
    sbuf2 = swk + sCR;
    outputf.WriteString( sbuf2 );
    ioutdata++;
    icount = iindata % 10000;
    if ( icount == 0 )
    {
      m_sMinputD.Format( "%d", iindata );
      m_sMoutputD.Format( "%d", ioutdata );
      SetDlgItemText( IDC_EINPUTD, m_sMinputD );
      SetDlgItemText( IDC_EOUTPUTD, m_sMoutputD );
      UpdateWindow();
    }
  } // while( 1 )
  inputf.Close();
  outputf.Close();
  m_sMinputD.Format( "%d", iindata );
  m_sMoutputD.Format( "%d", ioutdata );
  SetDlgItemText( IDC_EINPUTD, m_sMinputD );
  SetDlgItemText( IDC_EOUTPUTD, m_sMoutputD );
}




これで、リビルドして実行します。

郵便局から、ダウンロードしたcsvデータ から 項目を抽出してみましょう。


  項目位置:0,4,1

元のデータと比べてみてください。0番目、4番目、1番目 が 抽出できていればOKです。


なお、実行ファイルが必要な方はこちらからどうぞ。Yahoo JAPAN のブリーフケースから MVC501.exe をダウンロードしてください。
ダウンロードはこちら


今日は ここまでです。