第38講 データベースソフト(住所録)の制作=並列処理の練習☆☆
第9話 ファイルの各サブメニューのコードの解説その1
コード再掲
private: System::Void 名前を付けてToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
         SaveFileDialog^ w=gcnew SaveFileDialog();
         w->Filter="CSV形式(*.csv)|*.csv|すべてのファイル(*.*)|*.*";
         if(w->ShowDialog()!=System::Windows::Forms::DialogResult::OK)return;

         dcs(w->FileName);
         this->fn=w->FileName;
     }
private: System::Void 上書き保存ToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
         if(this->fn->Equals(L""))
           名前を付けてToolStripMenuItem_Click(sender, e) ;
         else
           dcs(fn);
      }
private: System::Void 開くToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
         OpenFileDialog^ w=gcnew OpenFileDialog();

         if(w->ShowDialog()!=System::Windows::Forms::DialogResult::OK)return;

         dco(w->FileName);
         this->fn=w->FileName;
      }
private: System::Void 閉じるToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
          Close();
}

bool dcs(String^ c){
  StreamWriter^ w=gcnew StreamWriter(c,false,System::Text::Encoding::GetEncoding("shift-jis"));
  char i,j;
  for(i=0;i<m;i++){
    for(j=0;j<18;j++){
      w->WriteLine(marshal_as<String^>(u[i][j]));
    }
  }
  w->WriteLine(w);
  w->Close();

  return(true);
}
bool dco(String^ d){
  dataGridView1->Rows->Clear();
  StreamReader^ r=gcnew StreamReader(d);
  marshal_context^ c=gcnew marshal_context();
  String^ mh;
  char i=0,j=0;
  while(1){
    mh=r->ReadLine();
    if(mh!=L"System.IO.StreamWriter"){
      u[j][i]=c->marshal_as<string>(mh);
      i++;
      if(i==18){
        i=0;
        j++;
      }
    }
    else
      break;
    }
    for(i=0;i<j;i++){
      dataGridView1->Rows->Add();
      dataGridView1[0,i]->Value=marshal_as<String^>(u[i][17]);
      if(u[i][0]=="1")dataGridView1[1,i]->Value=L"自宅";
      if(u[i][0]=="2")dataGridView1[1,i]->Value=L"会社";
      dataGridView1[2,i]->Value=marshal_as<String^>(u[i][1]);
      if(u[i][2]=="1")dataGridView1[4,i]->Value=L"様";
      if(u[i][2]=="2")dataGridView1[4,i]->Value=L"殿";
      if(u[i][2]=="3")dataGridView1[4,i]->Value=L"御中";
      if(u[i][2]=="4")dataGridView1[4,i]->Value=L"行";
      if(u[i][2]=="5")dataGridView1[4,i]->Value=L"宛";
      if(u[i][2]=="6")dataGridView1[4,i]->Value=L"係";
      if(u[i][2]=="7")dataGridView1[4,i]->Value=L"気付";
      dataGridView1[3,i]->Value=marshal_as<String^>(u[i][3]);
      if(u[i][4]=="1")dataGridView1[5,i]->Value=L"友人";
      if(u[i][4]=="2")dataGridView1[5,i]->Value=L"知人";
      if(u[i][4]=="3")dataGridView1[5,i]->Value=L"親類";
      if(u[i][4]=="4")dataGridView1[5,i]->Value=L"上司";
      if(u[i][4]=="5")dataGridView1[5,i]->Value=L"部下";
      if(u[i][4]=="6")dataGridView1[5,i]->Value=L"同僚";
      if(u[i][4]=="7")dataGridView1[5,i]->Value=L"取引先";
      dataGridView1[6,i]->Value=marshal_as<String^>(u[i][5]);
      dataGridView1[7,i]->Value=marshal_as<String^>(u[i][6]);
      dataGridView1[8,i]->Value=marshal_as<String^>(u[i][7]);
      dataGridView1[9,i]->Value=marshal_as<String^>(u[i][8]);
      dataGridView1[10,i]->Value=marshal_as<String^>(u[i][9]);
      dataGridView1[11,i]->Value=marshal_as<String^>(u[i][10]);
      dataGridView1[12,i]->Value=marshal_as<String^>(u[i][11]);
      dataGridView1[13,i]->Value=marshal_as<String^>(u[i][12]);
      dataGridView1[14,i]->Value=marshal_as<String^>(u[i][13]);
      dataGridView1[15,i]->Value=marshal_as<String^>(u[i][14]);
      dataGridView1[16,i]->Value=marshal_as<String^>(u[i][15]);
      dataGridView1[17,i]->Value=marshal_as<String^>(u[i][16]);
   }
   m=j-1;


   r->Close();
   return(true);
}
コードの解説
データを読み書きするためには、最初にファイルを開かなければなりません。
わかりやすい概念図が、日経BPソフトプレスの『ひと目でわかるVisual C++2008アプリケーション開発入門』のP173にあるのでそれを引用しましょう。
ファイルストリーム
現金は、データの比喩です。
現金を出し入れするためには、バックを開かなければならないように、
データの読み書きをするためには、まずファイルを開く必要があります。
そして、現金の出し入れが終わった後、バックを閉じておかないと現金がばらまかれたり、
予想外の時に現金が入ったりしてしまうので、バックを閉じるように、
開いたファイルも閉じなければなりません。
現金がばらまかれるというのは、あくまで比喩でもしファイルをオープンしたままにしておくと、
複数のアプリケーションが立ち上がっているとき、他のアプリケーションにデータを書き込まれ、
データに不整合が生じる可能性がありますので、データの読み書きが終わったらファイルは閉じなければなりません。

ファイルへのデータの読み書きの流れをファイルストリームといいます。
このファイルストリームを理解するに格好の概念図が、
『ひと目でわかるVisual C++2008アプリケーション開発入門』のP174にあるので再び引用しましょう。
ファイルダイアログボックス

ファイルのオープンとファイルストリームに関係している部分が、
bool dcs(String^ c){
  StreamWriter^ w=gcnew StreamWriter(c,false,System::Text::Encoding::GetEncoding("shift-jis"));
  char i,j;
  for(i=0;i<m;i++){
    for(j=0;j<18;j++){
      w->WriteLine(marshal_as<String^>(u[i][j]));
    }
  }
  w->WriteLine(w);
  w->Close();

  return(true);
}
bool dco(String^ d){
  dataGridView1->Rows->Clear();
  StreamReader^ r=gcnew StreamReader(d);
  marshal_context^ c=gcnew marshal_context();
  String^ mh;
  char i=0,j=0;
  while(1){
    mh=r->ReadLine();
    if(mh!=L"System.IO.StreamWriter"){
      u[j][i]=c->marshal_as<string>(mh);
      i++;
      if(i==18){
        i=0;
        j++;
      }
    }
    else
      break;
    }
    for(i=0;i<j;i++){
      dataGridView1->Rows->Add();
      dataGridView1[0,i]->Value=marshal_as<String^>(u[i][17]);
      if(u[i][0]=="1")dataGridView1[1,i]->Value=L"自宅";
      if(u[i][0]=="2")dataGridView1[1,i]->Value=L"会社";
      dataGridView1[2,i]->Value=marshal_as<String^>(u[i][1]);
      if(u[i][2]=="1")dataGridView1[4,i]->Value=L"様";
      if(u[i][2]=="2")dataGridView1[4,i]->Value=L"殿";
      if(u[i][2]=="3")dataGridView1[4,i]->Value=L"御中";
      if(u[i][2]=="4")dataGridView1[4,i]->Value=L"行";
      if(u[i][2]=="5")dataGridView1[4,i]->Value=L"宛";
      if(u[i][2]=="6")dataGridView1[4,i]->Value=L"係";
      if(u[i][2]=="7")dataGridView1[4,i]->Value=L"気付";
      dataGridView1[3,i]->Value=marshal_as<String^>(u[i][3]);
      if(u[i][4]=="1")dataGridView1[5,i]->Value=L"友人";
      if(u[i][4]=="2")dataGridView1[5,i]->Value=L"知人";
      if(u[i][4]=="3")dataGridView1[5,i]->Value=L"親類";
      if(u[i][4]=="4")dataGridView1[5,i]->Value=L"上司";
      if(u[i][4]=="5")dataGridView1[5,i]->Value=L"部下";
      if(u[i][4]=="6")dataGridView1[5,i]->Value=L"同僚";
      if(u[i][4]=="7")dataGridView1[5,i]->Value=L"取引先";
      dataGridView1[6,i]->Value=marshal_as<String^>(u[i][5]);
      dataGridView1[7,i]->Value=marshal_as<String^>(u[i][6]);
      dataGridView1[8,i]->Value=marshal_as<String^>(u[i][7]);
      dataGridView1[9,i]->Value=marshal_as<String^>(u[i][8]);
      dataGridView1[10,i]->Value=marshal_as<String^>(u[i][9]);
      dataGridView1[11,i]->Value=marshal_as<String^>(u[i][10]);
      dataGridView1[12,i]->Value=marshal_as<String^>(u[i][11]);
      dataGridView1[13,i]->Value=marshal_as<String^>(u[i][12]);
      dataGridView1[14,i]->Value=marshal_as<String^>(u[i][13]);
      dataGridView1[15,i]->Value=marshal_as<String^>(u[i][14]);
      dataGridView1[16,i]->Value=marshal_as<String^>(u[i][15]);
      dataGridView1[17,i]->Value=marshal_as<String^>(u[i][16]);
   }
   m=j-1;


   r->Close();
   return(true);
}
の部分です。この解説は次話で行いますが、
private: System::Void 名前を付けてToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
         SaveFileDialog^ w=gcnew SaveFileDialog();
         w->Filter="CSV形式(*.csv)|*.csv|すべてのファイル(*.*)|*.*";
         if(w->ShowDialog()!=System::Windows::Forms::DialogResult::OK)return;

         dcs(w->FileName);
         this->fn=w->FileName;
     }
private: System::Void 上書き保存ToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
         if(this->fn->Equals(""))
           名前を付けてToolStripMenuItem_Click(sender, e) ;
         else
           dcs(fn);
      }
private: System::Void 開くToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
         OpenFileDialog^ w=gcnew OpenFileDialog();

         if(w->ShowDialog()!=System::Windows::Forms::DialogResult::OK)return;

         dco(w->FileName);
         this->fn=w->FileName;
      }
private: System::Void 閉じるToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
          Close();
}
ではいったい何をしているのでしょうか。

第8話へ 第10話へ

戻る

VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)