• ベストアンサー

Visual BasicのProgressBerの設定方法

mdbファイルにADOで接続して、テーブルのデータを他のmdbファイルのテーブルにINSERT INTO句で追加するプログラムを作成しました。ところがデータが多くて処理に数分を要することもあり、ユーザーがフリーズしたものと思って、強制終了してしまうという事態が度々あって困っています。 そこで、ProgressBerの追加を検討しているのですが、インターネットやヘルプでいろいろ調べても設定方法がわかりません。よいアドバイスを頂けないでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • clavia
  • ベストアンサー率50% (5/10)
回答No.8

プログレスバーの方法はだいたい以下の様でいかがでしょうか? (temtecomai さんの方法に追加した状態です) ProgressBar1.Max = rsr1.RecordCount Do Until rst1.EOF  rst2.AddNew  rst2.Fields("苗字").Value=rst1.Fields("苗字").Value  rst2.Fields("名前").Value=rst1.Fields("名前").Value  rst2.Fields("生年月日").Value=rst1.Fields("生年月日").Value  rst2.Update  ProgressBar1.Value = ProgressBar1.Value + 1 Loop レコード件数ですが、 データベースへのアクセスに、ADO を使う場合は、これで取得できますが、 DAO の場合、レコードセットの開きかたによって、これでは取得できません。 このあたりは、ヘルプを参考に、試行錯誤してみて下さい。 また、プログレスバーの表示についてですが、普通は何もしなくても自動的に更新されます。(と思っています...) もしかすると、Hawk-W さんがおっしゃているようになっているのかもしれません。この場合、ProgressBar1.Refresh を Value を変更した後に実行してみて下さい。これで、再描画されると思います。(バージョンによって、このメソッドが無い場合があります。その場合は、Form1.Refresh のように、して下さい) DoEvents だと、システムに制御が戻るため、例えばボタンなどを押せないようにとか、ウィンドウを閉じないようにとか、いろいろとコーディングの追加が必要かと思います。(ただ個人的には、大変ですがこちらの利用をお勧めします。) 時間が許せば、2つとも試してみて、違いをぜひ体験してみて下さい。

momo-chan
質問者

お礼

どうもありがとうございました。 みなさんのお陰で、データ追加にかかる処理時間も短縮され(たような気がする)ましたし、プログレスバーの設定も上手くいきました。 結局次のように記述しました。 ProgressBar1.Visible = True ProgressBar1.Value = 0 ProgressBar1.Max = rst1.RecordCount rst1.MoveFirst Do Until rst1.EOF  rst2.AddNew  rst2.Fields("苗字").Value=rst1.Fields("苗字").Value  rst2.Fields("名前").Value=rst1.Fields("名前").Value  rst2.Fields("生年月日").Value=rst1.Fields("生年月日").Value  rst2.Update rst1.MoveNext  ProgressBar1.Value = ProgressBar1.Value + 1 Loop これで上手くいきました。 ありがとうございました。

その他の回答 (7)

noname#2494
noname#2494
回答No.7

どの様なコードでやっているのか分かりませんが、もしやっていたら御免なさい。 画面に変化が現れたのを更新する場合、そのままだと、処理がコードの内部でループしているので、画面が更新されません。画面を更新するには、一回システムに制御を戻す必要があります。 その場合には DoEvents をValueの更新後に置いてみてください。 objRecordset.AddNew ... ProgressBar1.Value = ProgressBar1.Value + 1 DoEvents こんな感じ?

momo-chan
質問者

お礼

どうもありがとうございました。 Value値の設定は、Loopを一回実行するたびに1増えていくということでいいのですね。実はとても難しく考えていました。現在のカレントレコードの位置を取得して、Max値の何パーセント終了して・・・・みたいなのを考えていました。 みなさんのおかげで、悲願のプログレスバーを設定することができました。 本当にありがとうございました。

  • clavia
  • ベストアンサー率50% (5/10)
回答No.6

「INSERT INTO」では、データベースエンジンから、VB に進行状況は教えてもらえないので、ProgressBar は無理かと思います。 「AddNew」なら、1件1件新規追加して行くので可能です。 ところで、処理時間が5分の1でも、元々数分かかっていたのでしたら、2、30秒はかかるので、進行状況は表示した方がいいのではと思います。ユーザーさんも状況がわかった方が安心されると思います。

momo-chan
質問者

補足

急に長期出張に出ることになり、今まで確認できませんでした。 返事が遅くなり申し訳ありません。 そうですよね。楽しいことをしていての2~30秒は短いかもしれませんが、動かないパソコンの画面を眺めていての2~30秒はとても長いですよね。 ということで、やはりプログレスバーを配置したいと思います。 そこで、下のTemtecomaiさんの例にならっていろいろやってみたところ、データの追加についてはAddNewメソッドで追加できるようになりました。しかし、Value値の設定が悪いのかどうか、プログレスバーがうまく進行してくれません。下の例でいうとValue値をどのように設定すればよいのでしょうか? よろしくお願いします。

noname#102878
noname#102878
回答No.5

ADOのレコードセット(更新可能なもの)のAddNewメソッドを実行するとカレントレコードが新規レコードに移動します。 Do Until rst1.EOF rst2.AddNew rst2.Fields("苗字").Value=rst1.Fields("苗字").Value rst2.Fields("名前").Value=rst1.Fields("名前").Value rst2.Fields("生年月日").Value=rst1.Fields("生年月日").Value rst2.Update Loop ちょっと手元にAccessがないので自信ないですが、おおむねこんな感じだったと思います(^_^;; 詳しくはヘルプを見てください。 追加するレコードセットをrst1とします。(読取専用でOK) 追加される側のレコードセットをrst2とします。(追加可能なセットで開く) rst1の最終レコードまでループします。 その中で、rst2をAddNewすると、rst2のカレントレコードが新規レコードに移動します。 そしてrst2の各フィールドに対してrst1の値を入力していく。必要な全てのフィールドに対して行ないます。 rst2の新規レコードは「浮いた状態」なので、Updateメソッドを行なうとrst2に追加更新されます。

momo-chan
質問者

お礼

みなさんのお陰で、プログレスバーを上手く設定することができました。 ありがとうございました。

momo-chan
質問者

補足

急に長期出張に出ることになり、今まで確認できませんでした。 返事が遅くなり申し訳ありません。 AddNewメソッドでのデータの追加うまくいきました。 ところで、プログレスバーの設置はあきらめようかと思っていたのですが、せっかくLoopを使うのだから、また、上のclaviaさんのご回答でも指摘されたように、やはりプログレスバーを検討しています。そこでいろいろやってみたのですが、Value値の設定が悪いのかどうか、プログレスバーがうまく進行してくれません。この例でいうとValue値をどのように設定すればよいのでしょうか? よろしくお願いします。

noname#2494
noname#2494
回答No.4

>私的にはrs.RecordCountで行数を取得できるのではないかと考えているのですが、いかがでしょうか? そのとおりです。MaxにRecordCountを代入すればよいと思います。 >今書いているコードはSQLで一度にデータ全てをINSERTする様に記述しています。 はふ。それでは、ちょっと出来ないですね。 対策方法としては、10回くらい更新したら、それで一旦戻ってきてValueを増やすとか、もしくは、temtecomaiさんに言う方法ならば一回ずつ戻ってこられますね。 戻ってきた時にValueを変更すればよいわけです。

momo-chan
質問者

補足

急に長期出張に出ることになり、今まで確認できませんでした。 返事が遅くなり申し訳ありません。 INSERT INTOではプログレスバーの配置は無理なようなので、Loopでやりたいと思います。そこでTemtecomaiさんの例でLoopさせ、データの追加ができるようになりました。ところがValue値の設定が悪いのかどうか、プログレスバーがうまく進行してくれません。temtecomaiの例でいうとValue値をどのように設定すればよいのでしょうか? よろしくお願いします。

noname#102878
noname#102878
回答No.3

視覚的な手法は#1さん、#2さんのどちらも有効なので、私は別の書き込みを。 アクションクエリーであるINSERT INTO句とADOレコードセットのAddNewはどちらが速いのか。 参考URLによると相手がAccessデータベースならAddNewの方が5倍以上速い、と書いてあります。 ご参考まで。 # 話は戻りますが、#1さんと#2さんの方法を使用するとして、Max値とカレント値のとり方はご存知ですよね? まぁループで処理してるんでしょうから余計なお世話か(^_^;;

参考URL:
http://homepage2.nifty.com/inform/vbdb/addnew.htm
momo-chan
質問者

補足

ご回答ありがとうございます。 私はVB超初心者でして、ループ処理とかがよくわかりません。 >参考URLによると相手がAccessデータベースなら >AddNewの方が5倍以上速い、と書いてあります。 実は以前インターネットでいろいろ調べているときにこれと同じような記述を見つけ、Addnewを試したことがあるのですが、よく分からなくて結局INSERT INTO句を採用したという経緯があります。 今書いているコードは cn.Execute "INSERT INTO テーブル1 SELECT * FROM テーブル1 IN '' [ms access;database=C:\DB\sample.mdb;PWD="password"] " というもので外部データベースのテーブルからデータを追加するというものです。 この処理をもしAddnewメソッドに書き換えることで、処理時間を5分の1以下に短縮できるのであれば、とくにプログレスバーは必要ないので、Addnewを採用したいのですが、コードの記述法がよくわかりません。よいアドバイスをお願いできないでしょうか?

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.2

100%完了(Max)の幅のラベルコントロール(a)をフォームに貼りつけ、同じ高さのもう一つのラベルコントロール(b)を左端を重ねて固定し、何かの事象に関連させて、右へ幅を増やして行き、右辺を徐々に右へ動かす。Bの背景色は、a(例えば白色)とは別色にして目立つようにする。こう言う方法を本で読んだ記憶があります。

momo-chan
質問者

補足

ご回答ありがとうございます。 >何かの事象に関連させて、右へ幅を増やして行き、右辺を徐々に右へ動かす 何らかの事象に関連させる方法がわかりません。 よいアドバイスをお願いします。

noname#2494
noname#2494
回答No.1

MSDNは持っていませんか? また、インターネットのMSDNにもありそうですが調べてみてください。 簡単な使い方というと、 ProgressBar.Minと ProgressBar.Maxを指定して、 ProgressBar.Valueで値を変更します。 例えば、質問の例では、 Insertする行数をMaxにして Minを0にします。 そして、一つのInsertをした時に、Valueを+1すれば、動いていく様に出来ると思います。

参考URL:
http://msdn.microsoft.com/library/
momo-chan
質問者

補足

ご回答ありがとうございます。 実はVBの初心者なものでして、その先がよくわかりません。 Maxの行数はどの様に取得するのですか?私的にはrs.RecordCountで行数を取得できるのではないかと考えているのですが、いかがでしょうか? また、Maxを設定したとして、Valueの値はどの様にすればよいのですか? 今書いているコードはSQLで一度にデータ全てをINSERTする様に記述しています。 よろしくお願いします。

関連するQ&A

  • Accessのインポートについて

    A.MDBの「まとめテーブル」にB.MDBの「テーブル1」とC.MDBの「テーブル2」を追加したいのです。 Insert Into を使ったら良さそうなのですが、記述がよく分かりません。 プログラムはA.MDB側で記述したいのですが…。 お願いいたします

  • Access2000の追加クエリ(INSERT句)について

    Access2000で作成したmdbファイルAから他のmdbファイルBにあるテーブルデータを取得して、mdbファイルAのテーブルにこのデータを追加する構文として、 DoCmd.RunSQL "INSERT INTO テーブル1 SELECT * FROM テーブル2 IN ""Z:\mdbファイルB.mdb""", -1 を記述して使用していますが、mdbファイルB.mdbにデータベースパスワードを設定すると、「実行時エラー・パスワードが正しくありません」のエラーが発生します。 接続先のmdbファイルBにパスワードを設定した状態で使用したいのですが、何かよい解決策はないでしょうか? なお、上記のとおりパスワードを設定した状態でテーブルにデータを追加できさえすればどんな方法でもかまいませんのでご教授願えないでしょうか。 よろしくお願いします。

  • [AC2000]SQLで追加若しくは更新する考え方

    会社で店舗毎での勤怠管理のソフトの作成を指示されたのですが、 各店舗はVPN(GA)でネットワーク化されており、本社にファイルサーバーがあります。 しかし、会社のデータベースソフトはAccess2000しか無いので、本社のサーバーにデータ用のMDBを置き、各店舗には入力用のMDBを置き、本社では管理用のMDBを置こうと思います。 本題なのですが、リンクテーブルを使用すると当然重く、同時に各店舗から入力するのが困難なので、SQL(INSERT INTOとUPDATE)で制御しようとしたのですが、データがあったら更新、無ければ追加する、の様な条件制御をSQLで出来るのでしょうか? ADOでやれば出来るのですが、スキルアップの為悩んでいます。 考え方をご教授頂ければ、後は作成中のMDBに応用させて見たいと思いますので、宜しくお願いします。

  • 他のMDBのテーブルに追加したい

    Access2010のADOについてご質問します。 以下のようにして、データを追加しています。 Dim SQL As String Dim cn As ADODB.Connection Set cn = CurrentProject.Connection ' SQL = "INSERT INTO テーブルA ( 勤務時間 ) " SQL = SQL & "SELECT [テーブルA ].[勤務時間] " SQL = SQL & "FROM テーブルA ; " cn.Execute SQL ご質問したいのは、 当MDB(PC)から社内サーバーにあるMDBのテーブルに追加したいのです。 違うテーブル名でしたら、リンクをすれば済む話とは思いますが 同じテーブル名の「テーブルA」なので どのようにすればいいのか困っています。 ご指導の程をよろしくお願いします。

  • ACCESSリンクテーブルでデータを入力しても表示されない。

    ACCESSリンクテーブルでデータを入力しても表示されない。 MS ASSECC2003を使っています、 ORG_data.mdbに元データがあります USER.mdbからリンクテーブルで上記ORG_data.mdb のテーブルを参照しています。 USER.mdbを開いてORG_data.mdbのテーブルに新規データを追加しても USER.mdbをいったん閉じて再度開かないと追加されたデータが見えません 元データのORG_data.mdbのテーブルにはデータが追加されいますが、 リンクテーブルの設定とかあるのでしょうか? USER.mdbで追加したデータがすぐに更新されて見れる方法はありませんか? どなたかお知恵を拝借させてください。 リンクテーブルで参照

  • mdbのテーブルを別のmdbのテーブルに追加

    2種類のMDBがあり 一つは 毎日の入力にて使用、もう一つは 累積として使用している。 それぞれに 同一デザインのテーブルがあります。 毎日の入力用のMDB内ののテーブルのデータをすべて 二つ目のMDBのテーブルに 追加したいのですが 一件読み込んで 一件書き込むなどと プログラムしていましたが 毎日の入力用のMDBが たくさんになったため 処理が遅くてたいへんです。 なにか 簡単に かつ 高速にすることは可能でしょうか? 開発環境は VB6 SP6 WindowsXP ADOを使用しています。 よろしくお願いします。

  • Access起動中にエクセルからADOでデータの更新ができない

    こんばんは。原因がわからないので質問させてください。 SQLサーバーのデータをAccessのmdbへリンクテーブルしています。 (SQLサーバー → Access) 全て一つのパソコンで行なっています。(LANには接続していません) Accessのmdbファイルを起動している時に ExcelからSQLサーバーのAccessにリンクしている上記のテーブルへ ADOを使ってデータを追加しています。 (Excel → Access)  しかし、「rs.Update」の部分で  「ODBC--リンク テーブル'テーブル1'での更新に失敗しました。」 となってしまいます。 なので、一度mdbファイルを落として、コードを再開すると通るので ADOでExcel → Accessにデータを追加し終わってから再度mdbファイルを立ち上げています。 また同じ状態(mdbファイルを起動)で Excel → SQLサーバー へ更新クエリをしようとすると「時間切れになりました」となります。 (こちらもmdbファイルを落とすと再開できます。) いちいちmdbファイルを落とすのめんどうなのですが 回避する方法はありますか? cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & "C:\Users\Documents.test.mdb" rs.Open "テーブル", cn, adOpenStatic, adLockPessimistic rs("フィールド") = True rs.Update '保存 rs.Close: Set rs = Nothing というコードを書いています。 Accessを落とせば正常に動きます。 ご教授よろしくお願い致します。

  • エクセルからアクセスへADO 「_be.mdb」に追加するべき?

    リンクテーブルでtest.mdbとtest_be.mdbに分割した場合 エクセルからアクセスへADOでテ゛ータを追加する場合、 「test.mdb」と「test_be.mdb」のどちらに追加すればいいのでしょうか? 「test_be.mdb」はリンクテーブルとして「test.mdb」のテーブルのみ保存されています。

  • ADO(js) insert into高速化

    ADO素人です。色々検索したのですが、見つからず質問いたします。 仕事場にてjavascript,ADO,mdb,XP,IE6を使用しDBを作成しております。 mdbのデータを加工しcsv出力しようと思っているのですが、非常に遅く困っております。 単純に、以下のコードで100件出力しても4秒ほどかかります。 環境的に上記を使用するしかない状況で、高速化するにはどのようにすればいいのでしょうか。 どなたか、何卒ご教示お願いいたします。 var dbobj = new ActiveXObject("ADODB.Connection"); dbobj.open("Driver={Microsoft Access Driver (*.mdb)};DBQ=e:db1.mdb;") for(var i=0:i<100;i++){ dbobj.Execute("insert into [Text;Database=e:;].[test.csv] (aaa) values('1111');"); } dbobj.close(); 上記を実行すると4秒ほどかかります。 実際はfield数20、300行ほどです。 出力データを新しいtableに作成し、そこから select * into [CSVファイル] from table作成 にすれば1秒かかりません。 が、例のようにループで出力したいと思っております。 お忙しいところ大変お手数ではございますが、どうぞよろしくお願いいたします。

  • ADOを覚えれば可能?

    accessで複数のパソコンから同時にMDBファイルを開いて テーブルの追加・更新などを行いたい場合は、ADOの知識があれば可能ですか? 複数のPCで一つのファイルを開いた場合、 読み取り専用になってしまいテーブルの更新ができません。 VBAのADOを覚えれば回避できるのでしょうか?