質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

Q&A

3回答

1341閲覧

Access2013にて.NETのようなDataGrid表示はできますか?

unto

総合スコア6

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

1グッド

0クリップ

投稿2018/02/28 14:58

編集2018/02/28 16:06

前提・実現したいこと

Access2013にてシステムを作成しております。
当方.NETでの経験は長いほうなのですが、Accessに関しては初心者同様で困っております。

◆質問1
Accessのフォームにおいても、.NetのようなDataGridは扱えるのでしょうか?
Accessのクエリなどを使わず、SQLをコードで記載、実行しDataGridに表示したいと
考えております。
また、Datagirdにてデータを書き換えても「更新ボタン」押下まで
テーブルにには反映させない仕様です。

Viewが利用できると思っておりましたが、それもできないようで、
内部的にデータテーブルでデータを管理するしかないと考えております。

◆質問2
上記Accessでの実装が難しいのであれば、.NETでの開発も視野に入れております。
.NetからAccess2013への接続、データ取得はうまくいきましたが、
Accessのテーブル名称を取得する際に権限のエラーが出てしまいます。
Accessを前バージョンへ保存も試みましたが、うまくいきません。

ご助言をお願い致します。。

追記です。

以下の処理をC#にて実行しました。

C#

1 string connectionString = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=C:\Dev\sample.accdb; Uid =; Pwd =; "; 2 string queryString = "SELECT MSysObjects.Type, MSysObjects.Name, MSysObjects.Flags FROM MSysObjects where MSysObjects.Flags = 0 AND Type = 1 ORDER BY MSysObjects.Type, MSysObjects.Name; "; 3 DataTable dt = new DataTable(); 4 5 // 読み込み 6 try 7 { 8 using (OdbcConnection connection = new OdbcConnection(connectionString)) 9 { 10 connection.Open(); 11 12 OdbcDataAdapter adapter = new OdbcDataAdapter(queryString, connection); 13 adapter.Fill(dt); 14 15 dataGridView1.DataSource = dt; 16 } 17 } 18 catch (Exception ex) 19 { 20 MessageBox.Show(ex.Message); 21 return; 22 }

adapter.Fill(dt);
を実行した際に、エラーとして以下の内容が表示されます。

エラー内容
ERROR[42000][Microsoft][ODBC Microsoft Access Driver]
'MSysObjects'の読み取り権限がないので、レコードを読み取ることができません。

.NETからAccess2013のテーブル名称情報を取得することは無理なのでしょうか?

bochan2👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

.NetからAccess2013への接続、データ取得はうまくいきましたが、Accessのテーブル名称を取得する際に権限のエラーが出てしまいます。

DataTable に Access のテーブルからデータを取得できていて、DataGridView には表示できるということですか?

で、「Accessのテーブル名称を取得」とはどういうことでしょう? 質問に提示されているコードにはそのような操作は入ってないように見えますが、その操作が入っているとすると具体的にコードのどれですか?

それから、上記と、

adapter.Fill(dt); を実行した際に、エラーとして以下の内容が表示されます。

で言っていることが矛盾していませんか。adapter.Fill(dt) でエラーが出るということはデータの取得はうまくいってないということだと思うのですが?

・・・というように、意味が分からないことが多々ありますが、とりあえず一度 Visual Studio のウィザードを使って定番の構成のアプリを作ってみることを提案させてください。

DB が SQL Server の場合ですが、以下のチュートリアル、

チュートリアル : データベースへのデータの保存 (単一テーブル)
https://msdn.microsoft.com/ja-jp/library/0f92s97z(v=vs.120).aspx

・・・のように Visual Studio のデータソース構成ウィザードを利用して型付 DataSet + TableAdapter を作って、それを利用してアプリを作ると、以下のページの図のような構造のアプリが、ほとんど自分でコードを書くこと無しに作れます。

Windows フォーム アプリケーションでのデータへの接続
https://msdn.microsoft.com/ja-jp/library/wxt2cwcc(v=vs.120).aspx

Access でもウィザードが使えますので、同様なことができます。(注)

操作に慣れると 10 分もかからず作れるはずです。今回のような問題に悩むことはなくなり、開発工数は激減するはずです。保守工数も減るはずです。お試しください。

(注)Access でオートナンバーを使っている場合、INSERT した時に DB 側で設定したオートナンバー値を DataSet に書き込むところまでは面倒を見てくれないという点が SQL Server とは違いまが、それを解決する方法はあります。詳しくは以下の記事を見てください。

Access の更新
http://surferonwww.info/BlogEngine/post/2010/09/04/Updating-Access.aspx

【追伸】

今回の問題とは関係ない余計なお世話かもしれませんが、Exception をキャッチするのは止めた方がいいです。理由は以下の記事を見てください。

NETの例外処理 Part.1
https://blogs.msdn.microsoft.com/nakama/2008/12/29/net-part-1/

.NETの例外処理 Part.2
https://blogs.msdn.microsoft.com/nakama/2009/01/02/net-part-2/

.NET 4 からは破損状態例外は catch できなくなっているそうですが、「それでも Catch (Exception e) を使用するのはよくない」ということについては以下の記事を見てください。

破損状態例外を処理する
https://msdn.microsoft.com/ja-jp/magazine/dd419661.aspx

【2018/3/2 13:30 追記】

下の 2018/03/02 12:50 の私のコメントで「OleDbConnection.GetSchema メソッドを利用するのがよさそうです。具体的な方法は別途回答欄に追記しておきます」と書きましたが、それを以下に書きます。

詳しい説明が書いてある Microsoft の文書が見つからず、やってみた結果で判断してますので、ホントにそれで全てのケースで問題なくテーブル名が取得できるのかという不安は若干ありますが・・・

OleDbConnection.GetSchema メソッド (String) の引数(返すスキーマの名前)を "Tables" とすると、テーブルのスキーマ情報(テーブル名を含む)を格納した DataTable が返ってきます。

OleDbConnection.GetSchema メソッド (String)
https://msdn.microsoft.com/ja-jp/library/ms135982(v=vs.110).aspx

DataTable の中には VIEW やシステムテーブルも含まれていますが、テーブルの種類の情報も含まれているのでそれを見てテーブル名のみを取得できます。

DataTable の 3 番目の列にテーブル名が、4 番目の列に種類が格納されているので、種類が "TABLE" ものを取得すれば良いはずです。

以下のコードは、Microsoft のサンプル Northwind2007.accdb からその中のテーブル名を取得する例です。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data.OleDb; using System.Data; using System.Data.SqlClient; namespace ConsoleAppAccess { class Program { static void Main(string[] args) { using (OleDbConnection conn = new OleDbConnection()) { conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\"C:\Users\...\Northwind2007.accdb\""; conn.Open(); string collectionName = "Tables"; DataTable table = conn.GetSchema(collectionName); foreach (DataRow dataRow in table.Rows) { if (dataRow[3].ToString() == "TABLE") { Console.WriteLine(dataRow[2]); } } } } } }

結果は以下の通りで、Northwind2007.accdb に含まれるテーブル名として間違いないことは確認しました。

Budget
Categories
Categories 2003
Customers
Customers 2003
Employee Privileges
Employees
Employees 2003
Inventory Transaction Types
Inventory Transactions
Invoices
Monthly Orders
Order Details
Order Details 2003
Order Details Status
Orders
Orders 2003
Orders Status
Orders Tax Status
Privileges
Products
Products 2003
Purchase Order Details
Purchase Order Status
Purchase Orders
Sales Reports
Shippers
Strings
Suppliers
Suppliers 2003
Switchboard Items

投稿2018/03/01 01:30

編集2018/03/02 04:31
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YAmaGNZ

2018/03/01 15:37

AccessにはMSysObjectsというシステムテーブルがあってそこにテーブル名等の情報があります。 ですので、queryStringに設定しているSQLがそれにあたることになるかと思います。(SQLが合っているかは検証していませんが)
退会済みユーザー

退会済みユーザー

2018/03/02 03:50

> queryStringに設定しているSQLがそれにあたることになるかと思います。 失礼しました。クエリに目が行ってなかったです。提示されていたコードはテーブルからデータを抽出して DataDridView に表示するものだと思い込んでました。 .NET の C# アプリからテーブルデータを取得するのは問題なくできていて、現在の課題は接続先の .accdb ファイルにあるテーブル名を取得するということでいいのですね? 'MSysObjects' に読み取り権限を与えるのは、自分が調べた限りですが、方法が見つからないです。(Zuishin さんが紹介された記事も読みましたが) なので、OleDbConnection.GetSchema メソッドを利用するのがよさそうです。具体的な方法は別途回答欄に追記しておきます。
guest

0

質問1
Access は .NET でないので同じものはありません。
Accessのフォームでデータを一覧で表示できるようにする方法
フォームの種類(単票・表・データシート・帳票)

質問2
teratail を使っている人たちと比べて開発が長い方なのならどのように聞けばいいかわかるのではありませんか?
長年エラーメッセージを読まずに済ませたのですか?

投稿2018/02/28 15:17

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

unto

2018/02/28 16:01

ご返信いただき大変有難う御座いました。 また、質問内容に関し、不足事項があり大変申し訳ございません。 プロの方々からご回答をいただけると期待してしまい、内容を割愛してしまいました。。 今後気を付けて参ります。 質問2に関しての追記致しました。 何卒、ご助言いただきたく宜しくお願い致します。。
Zuishin

2018/02/28 16:02

プロはエラーメッセージを読まないのですか?
unto

2018/02/28 16:08

いえいえ。そういった意味ではございません。 お気を悪くしてしまったら申し訳ございません。 長年経験している方は「あーこの問題ねー」と推測できるものなのかと思っておりました。 大変失礼いたしました。
Zuishin

2018/02/28 16:13 編集

何の手がかりも無いのにあーこの問題ねーとすぐ見当がつくほどよくある問題ならエラーメッセージでググればすぐ解決方法が見つかりますので次回からはエラーを無視しないでください。
unto

2018/02/28 16:36

Zuishinさん いろいろとご助言いただきありがとうございました。 今後気を付けていきます。
guest

0

質問1について、Accessの実装を考えた場合以下のようになるかと思います。

・accessにワークテーブルを持ち、そのテーブルをレコードソースとして指定する。
・表示や更新の場合、そのワークテーブルを介在として実テーブルへはSQLでアクセスする。

上記とすることで、排他の管理も実テーブルにアクセスする瞬間に限定でき、また、mdbのテーブルを利用することで、Accessの機能も利用できることになります。

投稿2018/03/01 01:01

sazi

総合スコア25173

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

unto

2018/03/01 02:01

saziさん コメント頂き有難うございます。 また不明点などありましたら質問してしまうかもしれませんが、 頂いた設計アイデアでチャレンジしてみます。 ありがとうございました。
sazi

2018/03/01 07:16

ワークテーブルを使用する際にはデータの追加削除の繰り返しになりますので、DBが肥大化して破損しないように、常に最適化されるようにして下さい。 ※ワークテーブルと言わず、アクセスのテーブルを使用する場合には最適化は必須と考えた方が良いですけど。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問