SQLの窓

2019年06月24日


Microsoft Access に対してSQLを入力してその結果を DataGridView に表示する最も簡単なコード



最初に .accdb か .mdb を選択しておいて、自由な SQL をタイプしてその結果をそのまま Excel のごとく DataGridView に表示します。

DataGridView に表示するデータは全て文字列扱いとして、ArrayList に随時行を追加して、Rows.Add に、ToArray() したものをセットします。

一応表示のみを想定しているので、以下の設定を最初にします


表示件数は多すぎると時間がかかりすきるので、固定で 100 件にしています。
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.OleDb;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinApp1 {
	public partial class Form1 : Form {

		private OpenFileDialog ofd = new OpenFileDialog();

		public Form1() {
			InitializeComponent();
		}

		private void button1_Click(object sender, EventArgs e) {

			using (OleDbConnection myCon = new OleDbConnection())
			using (OleDbCommand myCommand = new OleDbCommand()) {

				// *********************
				// 接続文字列の作成
				// *********************
				myCon.ConnectionString = string.Format($"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={ofd.FileName};");
				Debug.WriteLine(myCon.ConnectionString);

				// *********************
				// 接続
				// *********************
				try {
					// 接続文字列を使用して接続
					myCon.Open();
					// コマンドオブジェクトに接続をセット
					myCommand.Connection = myCon;
					// コマンドを通常 SQL用に変更
					myCommand.CommandType = System.Data.CommandType.Text;
				}
				catch (Exception ex) {
					MessageBox.Show(this,ex.Message);
					return;
				}

				// *********************
				// 実行 SQL
				// *********************
				myCommand.CommandText = textBox1.Text;

				// *********************
				// レコードセット取得
				// *********************
				try {
					using (OleDbDataReader myReader = myCommand.ExecuteReader()) {

						// *********************
						// 列数
						// *********************
						int nCols = myReader.FieldCount;

						// DataGridView 初期化
						dataGridView1.Columns.Clear();
						dataGridView1.DataSource = null;
						dataGridView1.ColumnCount = nCols;		// カラム数

						Type fldType;
						ArrayList rowData = new ArrayList();

						// データ取得と表示
						int maxCount = 0;
						while (myReader.Read()) {

							// 行データをセットする ArrayList をクリア
							rowData.Clear();

							maxCount++;
							if ( maxCount > 100 ) {
								break;
							}

							// 初回のみ、タイトル文字列を設定
							if (maxCount == 1) {
								for (int idx = 0; idx < nCols; idx++) {
									dataGridView1.Columns[idx].Name = myReader.GetName(idx);
								}
							}

							// 行データの作成( ArrayList で作成して ToArray() したものを Rows.Add )
							for (int idx = 0; idx <nCols; idx++) {

								// NULL でない場合
								if (!myReader.IsDBNull(idx)) {
									// 列のデータ型を取得
									fldType = myReader.GetFieldType(idx);

									// 文字列
									if (fldType.Name == "String") {
										rowData.Add(myReader.GetValue(idx).ToString());
									}
									else if (fldType.Name == "Int32") {
										rowData.Add(myReader.GetInt32(idx).ToString());
									}
									else if (fldType.Name == "DateTime") {
										rowData.Add(myReader.GetDateTime(idx).ToString());
									}
									else {
										rowData.Add(myReader.GetValue(idx).ToString());
									}

								}
								else {
									rowData.Add("");
								}
							}

							// 行追加
							dataGridView1.Rows.Add(rowData.ToArray());

						}

						// リーダを使い終わったので閉じる
						myReader.Close();
					}
				}
				catch (Exception ex) {
					myCon.Close();
					MessageBox.Show(this, ex.Message);
					return;
				}

				myCon.Close();

				// カラム幅の自動調整
				dataGridView1.AutoResizeColumns();

			}		// 最外の using の終わり

		}

		private void button2_Click(object sender, EventArgs e) {

			// *********************
			// ファイル選択
			// *********************
			ofd.Filter = "Excel(*.mdb;*.accdb)|*.mdb;*.accdb|すべてのファイル(*.*)|*.*";
			ofd.FilterIndex = 1;
			ofd.Title = "Access データベースを選択してください";
			ofd.RestoreDirectory = true;

			if (ofd.ShowDialog() != DialogResult.OK) {
				return;
			}


		}		// click イベントの終わり

	}		// class の終わり
}


※ テーブル・ビュー一覧は以下のようにして簡単に表示できます
using (OleDbConnection myCon = new OleDbConnection())
using (OleDbCommand myCommand = new OleDbCommand()) {

	// *********************
	// 接続文字列の作成
	// *********************
	myCon.ConnectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};", ofd.FileName);
	Debug.WriteLine(myCon.ConnectionString);

	// *********************
	// 接続
	// *********************
	try {
		// 接続文字列を使用して接続
		myCon.Open();
		// コマンドオブジェクトに接続をセット
		myCommand.Connection = myCon;
		// コマンドを通常 SQL用に変更
		myCommand.CommandType = System.Data.CommandType.Text;
	}
	catch (Exception ex) {
		MessageBox.Show(this,ex.Message);
		return;
	}

	DataTable dataTable = myCon.GetOleDbSchemaTable(
		OleDbSchemaGuid.Tables,
		new object[] { null, null, null, null }
	);
	// TABLE のみの場合は以下( 上記は 全て )
	//	new object[] { null, null, null, "TABLE" }

	dataGridView1.Columns.Clear();
	dataGridView1.DataSource = dataTable;

	myCon.Close();

	// カラム幅の自動調整
	dataGridView1.AutoResizeColumns();

}		// 最外の using の終わり

さらに SQL の実行結果は、データの途中加工が全くできなくなりますが、DataTable を使って以下のようにさらに短く記述する事ができます
// *********************
// 実行 SQL
// *********************
myCommand.CommandText = textBox1.Text;

try
{
	using (OleDbDataReader myReader = myCommand.ExecuteReader())
	{
		DataTable dataTable = new DataTable();

		dataTable.Load(myReader);

		dataGridView1.Columns.Clear();
		dataGridView1.DataSource = dataTable;

		myReader.Close();
	}

}
catch (Exception ex)
{
	myCon.Close();
	MessageBox.Show(this, ex.Message);
	return;
}

DataSource プロパティを使用した場合、新たに直接データをセットしていきたい場合は、いったん DataSource プロパティに null を設定しておく必要があります。


Microsoft.ACE.OLEDB.12.0 がインストールされていない場合

Microsoft Access データベース エンジン 2010 再頒布可能コンポーネントをダウンロードしてインストールします。


( 32ビット版と64ビット版があるので選択してダウンロードします )




posted by lightbox at 2019-06-24 19:53 | VS(C#) | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり