第38講 データベースソフト(住所録)の制作=並列処理の練習☆☆
第11話 ファイルの各サブメニューのコードの解説その3
コード再掲
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);
}
コード解説
dcs(w->FileName);
this->fn=w->FileName;
のw->FileNameは、
ファイル→として
ファイル名を入力したときの名前(この例では住所録データ1)
に相当します。
w->FileNameは、wのFileNameという意味でしたね。
つまり、dcs(w->FileName)はdcs(L"住所録データ1")と同じです。
次のthis->fn=w->FileName;はなんでしょうか。
そもそも、fnとは何だとお思いでしょうが、fnは実はただのString^型の変数です。
これがどこで宣言してあるかと申しますと、
#pragma once
#include"stdafx.h"
#include"Form2.h"
namespace 住所録 {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Threading;
using namespace IO;
/// <summary>
/// Form1 の概要
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
String^ fn;
Form1(void)
・
・
・
つまり、ただのグローバルString^型変数にすぎません。
変数名自体には意味はありません。
変数とはデータを入れる箱です。
そして、変数名はその箱のラベルにすぎません。
fnはまさにString^型のデータを一時的に貯めておくための箱にすぎません。
では何のためにデータを貯めておくのでしょうか。
それは、『上書き保存する』ときに必要になるからです。
private: System::Void
上書き保存ToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e)
{
if(this->fn->Equals(L""))
名前を付けてToolStripMenuItem_Click(sender, e) ;
else
dcs(fn);
}
上書き保存のときは、ファイル名は同名でよいので、一時箱に入れておいてそれを使えばよいわけです。
全くちんぷんかんぷんだった
dcs(w->FileName);
this->fn=w->FileName;
の2行の意味が少し見えてきたのではないですか。
もちろん、関数dcs(L"住所録データ1")の中身は全くまで説明していませんので、
中はまだブラックボックスのままです。
次話で内容は詳しく説明しますが、簡単に述べておくと、
『住所録データ1』というファイルを開き、データを書き込むことが任務です。
『えっ、名前を付けて保存でデータを保存したはずでは?』ですって。
実は、名前を付けて保存では、データを入れるバック(金庫)を作っただけで、
データはまだ書き込んでいません。
private: System::Void 名前を付けてToolStripMenuItem_Clickの任務はファイルを作ること=データを入れるバックを作ることであり、
関数dcs(L"住所録データ1")の任務がそのバックをあけてお金を入れること(データを書き込むこと)なのです。
ファイルとは、結局『住所録データ1』というラベルのついたバックににすぎないのです。
バックへの出し入れは、ファイルストリームといいましたね。
private: System::Void 名前を付けてToolStripMenuItem_Clickでは、お金を入れるバックを
用意して、そのバックの名前を『住所録データ1』にしたわけです。
というより『住所録データ1』という名前が織り込まれたバックを用意したと説明した方が適切でしょうか。
現在、バックが用意されただけで中身は空です。
ファイルストリームが現金の出し入れを行います。
それを行うのが関数dcs(L"住所録データ1")なのです。
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual
Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)