• ベストアンサー

Excelでのデータ挿入が上手くできない

naritanです。 マクロでシート上のデータを編集して帳票を出力しているExcelがあります。 そのExcelに対して、DBから取得したデータをシートに挿入して、ASPから 帳票出力マクロを実行させたいと思っています。 しかし、ExcelブックにDBから取得したデータを挿入すると、 スクリプトがタイムアウトになってしまいます。 DBから取得した1カラムだけ挿入すると上手くできるのですが、 27カラム(1レコード)を挿入するとスクリプトタイムアウトになってしまいます。になってしまうのでしょうか? 環境は、WinNtWS4.0 + Access2000 + PWS + Excel2000です。 以下に、その部分のソースを載せます。 ----------------------------------------------------------------------Set Exl = Server.CreateObject("Excel.Application") Set ExlBook = Exl.Workbooks.Open ("g:\hw_manage\Pc\5.xls") Set ExlSheet = ExlBook.Sheets("一覧") ExlSheet.Activate with ExlSheet i = 4 '//DB取得値(RsPrint)がEOFになるまでExcelにデータ挿入 Do until RsPrint.EOF .Range("A" & i).value = RsPrint("STAT_FG") .Range("B" & i).value = RsPrint("MAKER_NM") .Range("C" & i).value = RsPrint("MODEL_NM") .Range("D" & i).value = RsPrint("CPU") ~省略~ i = i + 1 Loop end with ----------------------------------------------------------------------

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

  • ベストアンサー
  • msystem
  • ベストアンサー率42% (79/186)
回答No.3

タイムアウトということから考えると、スクリプトの実行時間が長すぎるということですよね。 ということは、スクリプトの実行時間を減らすことを考える必要があります。 ソースの中で、Server.CreateObject、Workbooks.Openがありますが、このあたりは、非常に時間のかかるコマンドだと思います。 実際このあたりでタイムアウトしてそうだということですので、このあたりを直す必要があります。(ソースがコピー&ペーストかどうかはわかりませんが、5.xlsのファイルもネットワーク上にありそうですね。それだと余計に時間がかかりますね) せめて、Excelの起動を、セッション開始時かアプリケーションの開始時にすることはできませんか?それでも、Do・・・Loopでタイムアウトしそうですが・・・(Excelのオブジェクト操作は、割と重いように私は感じています。) あとは、タイムアウトの時間を延ばすことですが、レスポンスが悪いままなので、操作ユーザーは、トラブルなのかと心配になり、困ることになりそうですが、大丈夫でしょうか? もうひとつ思いつきました。 少し難しいですが、Excelにデータを挿入する機能を持った、非同期処理のできるActiveXコンポーネントを作成し、それをASPから呼ぶというのはどうですか?それなら、操作ユーザーも待ちませんし、ASPタイムアウトもなし。ただし、操作終了と、Excelでの処理は非同期ですので、すぐにそのファイルを開いても、操作は終了していませんが・・・ 目的がわからないで、なんともいえませんが、どうしてもExcelのファイルでなければならない理由がなければ、CSVファイルに出して、Excelに読ませるようにするほうが、よいような気がします。

forester
質問者

お礼

丁寧なご回答、ありがとうございます。 実は、つい先程、解決致しました。 原因は、Excelブックにあったみたいです。 試しに、モジュールを新規Excelにエクスポートして実行してみたところ、 サクサクッと処理が終了しました。もちろん、ExcelのVBAも正常に動作しています。 いろいろとお手数をお掛けしました。 ありがとうございました。

その他の回答 (2)

  • mnabe
  • ベストアンサー率33% (427/1283)
回答No.2

補足から...  多分Excelのオブジェクトの解放関連に問題がある様に思えます。  作成したオブジェクトはしっかり解放していますか?  それを先に確認して見て下さい。  マニュアル等では、自動的に解放と読める部分もありますが、タイミングによっては、解放を行ってくれないので、プログラムでしっかり解放してあげましょう。  それをやってから...。  Excelファイルの解放後に、少々時間を置くようにして見て下さい。直に取得すると、エラーになりやすいので......ね。

forester
質問者

補足

ご回答ありがとうございます。 オブジェクトの解放はちゃんと行っているのですが、 VBみたいに、エラー時にON ERROR GOTOで解放処理に飛ばす事ってできるのですか? リファレンスを見たところ、VBSにはON ERROR RESUMU NEXTしかなかったものですから・・・

  • mnabe
  • ベストアンサー率33% (427/1283)
回答No.1

 どのタイミングでタイムアウトになるのですか?  挿入した時? 挿入の結果待ち? 次の挿入を行う時? 2カラムではうまくいくの?(どこからエラーになるの?)  そもそも、Excelを使用している意味がわかりません。ASPで運用してるのですよね??  だったら、全部ASP上で行えばいいのでは?  今一度、Excelを使用する意味を考えてみて下さい。 私なら、データ加工までは全部Access2000+ASPだけで構築して、Excelは使用しない様にします。理由は、連携等は問題発生時にエラーの特定が難しいので...ね。  また、グラフの作成の必要があれば、グラフのコントロールをASPから使用すればいいのですし...。  どうしても、Excelを使用しなければならないのなら、別にISAPI等のアプリケーションを作成してしまって、安全に動作させる事を考えます。ね。

forester
質問者

お礼

naritanです。 補足に補足致します。 再度、各行にresponse.writeを書き、 タイムアウトのタイミングを調べてみた結果、 Set ExlBook = Exl.Workbooks.Open ("g:\hw_manage\Pc\5.xls") の直前に書いたresponse.writeまで表示されましたので、 上記の行でタイムアウトしているみたいです。

forester
質問者

補足

ご回答ありがとうございます。 タイムアウトになるのは、EXCEL.EXEのプロセスが残っていることから、 EXCEL起動後の何処かだと思います。 処理の流れとしては、 画面でデータ抽出条件を指定して、印刷ボタンをクリックして、ONCLICKメソッドでJAVASCRIPTに処理を移し、FORMをSUBMITして同画面を再読込し、EXCEL起動ロジックが実行される。 というものなのですが、印刷ボタンをクリックしても、接続している状態のままが面は変わらず、そのままタイムアウトしてしまっています。 画面が変わらないにも関わらず、EXCELが起動しているらしく、 プロセスに残ってしまっています。 EXCELを使用している意味は、既存EXCELのマクロが複雑に作られており、 1からACCESS等でリメイクするのも時間がかかると思ったからです。 試しに、既存EXCELのVBAをASPにINCLUDEして実行してみたのですが、 やはり、VBSではサポートされていないメソッドが多々あるらしく、 その部分を補正していくのも時間がかかると思い、諦めました。

関連するQ&A

  • EXCEL VBAマクロ作成で、他のEXCELからデータを取り込みたい

    メインプログラム(EXCEL VBA)より、 他のフォルダーにあるEXCELの項目の内容を取り込みたいです。 たとえば他のフォルダーのEXCELのRange("A2:A3").ValueをメインプログラムのRange("C2:C3").Valueにセットしたい時です。 ・コマンドボタン押したら、どこのEXCELから取り込むかのポップアップ(?)は、表示はできてます。 ・作業者が選んだパスとブックもMsgBoxで表示できてるので、もらう相手の場所も取得できてます。 ・となると次はOPEN,INPUTですか? テキストデータの取り込みですと、Inputでそのバッファを定義してるのですが、なんか違うような。。。 よろしくお願いします!

  • accessのデータをexcelに

    Office97使用のシステム管理初級者です。 accessのクエリーを利用して以下のようなシステムを作ろうと思っているのですが、行き詰っています。 (1) 特定のデータ(複数)を抽出 (2) 既に用意しているexcelの任意の位置にデータを移管 (3) excelのブックを別名にてフロッピーに保存 (1)は何とかできたのですが、(1)によって抽出できたデータを任意のexcelに移管する時、最初の1データしか移管できなくて困っています。(次のようなものです・・・。) Private Sub エクセル起動_Click() On Error GoTo Err_エクセル起動_Click Dim oApp As Object Set oApp = CreateObject("Excel.Application") oApp.Visible = True 'Only XL 97 supports UserControl Property On Error Resume Next oApp.UserControl = True oApp.Workbooks.Open FileName:="D:\****\123.xls" oApp.range("b4").Value = Me![1] oApp.range("c8").Value = Me![2] oApp.range("d8").Value = Me![3] oApp.range("e8").Value = Me![4] oApp.range("f8").Value = Me![5] oApp.range("g8").Value = Me![6] oApp.range("h8").Value = Me![7] oApp.range("i8").Value = Me![8] oApp.range("j8").Value = Me![9] Exit_エクセル起動_Click: Exit Sub Err_エクセル起動_Click: MsgBox Err.Description Resume Exit_エクセル起動_Click End Sub それぞれの行にズラーッとデータがきて、さらにそのexcelを別名にてフロッピーに保存したいのですが、どのようにすればいいのでしょうか? よろしくお願いします。

  • 【問題】ACCESSからEXCEL雛形(帳票レイアウト)を開き、データ

    【問題】ACCESSからEXCEL雛形(帳票レイアウト)を開き、データをセットして名前を付けて保存する流れですが、データセット時に「実行時エラー'13'型が一致しません。」が出て処理が止まります。 【詳細】 ACCESS2003 SP3 と EXCEL2003 SP3を使用しています。 簡単に説明しますと、ACCESSのフォームで集計条件を入力し実行ボタンを押下した後、ACCESSでデータの集計処理を行い、EXCEL雛形(帳票レイアウト)を開き、データをセットして名前を付けて保存する流れですが、処理が戻ってきません。データをセットする処理の前にMSGBOXを入れ"F8"で1ステップ毎に処理を進めますとセット1行目から「実行時エラー'13'型が一致しません。」が出て処理が止まります。 また、タスクマネージャのプロセスに"EXCEL.EXE"が常駐したままとなり、終了させるまでEXCEL雛形(帳票レイアウト)を開く事ができません。 【PG】 Private Sub 出力_Click() Dim DB As Database, X Set DB = CurrentDb() DoCmd.SetWarnings False Me!SUB01.SourceObject = "F_処理中" Me!SUB01.Requery X = 帳票出力A01(Me!表番号, Format(Me!年度, "yyyy"), Me!番号, Me!ファイル名, Me!シート名) Me!SUB01.SourceObject = "F_MASK" End Sub Public Function 帳票出力A01(表番号, 年度, 番号, ファイル名, シート名) ' On Error GoTo ERR_帳票出力A01 Dim DB As Database, T As Recordset, パス, 処理日時, X, i Set DB = CurrentDb() DoCmd.SetWarnings False 処理日時 = Format(Now(), "yyyymmddhhnnss") '<< 出力データ準備 >> X = 出力集計用(年度) Set T = DB.OpenRecordset("W_集計結果") If T.EOF Then MsgBox "出力可能データが存在しません。" Exit Function End If '<< EXCELへ書き出し >> パス = CurrentProject.Path Dim xlApp As Excel.Application Dim xlWkb As Excel.Workbook Dim xlWst As Excel.Worksheet Set xlApp = CreateObject("Excel.Application") Set xlWkb = xlApp.Workbooks.Open(パス & "\帳票出力レイアウト\" & ファイル名) Msgbox("この後エラーとなる。") xlWkb.Sheets(シート名).Cells(1, 16).Value = 番号  ←←← この行でエラー発生 xlWkb.Sheets(シート名).Cells(5, 4).Value = Format(CVDate(年度 - 1 & "/04/01"), "gggee年度") xlWkb.Sheets(シート名).Cells(5, 8).Value = Format(CVDate(年度 & "/04/01"), "gggee年度") xlWkb.Sheets(シート名).Cells(5, 12).Value = Format(CVDate(年度 + 1 & "/04/01"), "gggee年度") ----- 集計結果をEXCELに貼り付ける処理など以降省略 ----- よろしくお願い致します。

  • VB2005→Excelへの出力

    現在、以下環境にてシステム開発を行っています。 OS:WindowsXP DB:SQL Server 2005 画面系:Visual Studio 2005 (VB) 帳票系:Microsoft Office 2003 (Excel) ここで質問なのですが、 VBにて取得したデータ(DBから取得)を、 Excelファイルの帳票テンプレートの名前付きセルに貼り付けたいのですが、 方法がわかりません。VB、Excelでの開発(プログラミング)初心者です。 「Imports Microsoft.Office.Interop.Owc11」 をインポートしてるだけで停まっています。 情報足らずであれば、また追記します。 とりあえず要件まで。 宜しくお願いします。

  • エクセルVBA抽出がうまく出来ません

    エクセル2013VBA初心者です。 入力シートからDBシートへ、DBシートから印刷シートへのデータ転記と印刷、入力内容のクリアまでは出来るようになりました。 DBシートの検索を行い、記録内容を入力シートに転記する抽出を行いたいのですが、下記構文を書いたところで問題が発生しました。 If Sh2.Range("A & i").Value = j And Sh2.Range("B & i").Value = k Then  でとまります。メッセージは ‘Range’メソッドは失敗しました:‘Workshieet’オブジェクトというものです。 やろうとしていることは、入力シートに設けた“E12”と”G12”の二つの検索項目をキーにDBシートの行を特定し、この行の内容を入力シートに反映しようということです。 入力シートの検索項目“E12”、 ”G12”はそれぞれDBシートのA列、B列に格納されている項目で、年度と連番です。サンプルとして入力シート"C5"に抽出しようとしているDBシートD列は申請者名です。 恐れ入りますがよろしくご教示頂きたく、お願い申し上げます。 Sub DBシートから力情報を抽出する () Dim Sh1 As Worksheet Dim Sh2 As Worksheet Dim i As Long Dim j As Long Dim k As Long Set Sh1 = Worksheets("入力") Set Sh2 = Worksheets("DB") j = Sh1.Range("E12").Value k = Sh1.Range("G12").Value With Sh2 For i = 2 To .Range("A" & Rows.Count).End(xlUp).Row If Sh2.Range("A & i").Value = j And Sh2.Range("B & i").Value = k Then Sh1.Range("C5").Value = Sh2.Range("D & i").Value End If Next  End With End Sub

  • ExcelVBAでAccessのデータを検索する

    Excel  VBA で、ADOを用いてAccess のデータを検索するにはどうしたらいいですか。 やりたいこと 検索結果を、Excel のセルにコピーすること。 ソースコード 'MDBファイルに接続します Set db = New ADODB.Connection db.Provider = "Microsoft.Jet.OLEDB.4.0" db.Open "C:\Database\test.mdb" 'レコードセットを開きます Set rs = New ADODB.Recordset 'テーブルを開きます rs.Open "PT_MST", db, adOpenForwardOnly, adLockReadOnly findName = ws.Cells(i, 1) & ws.Cells(i, 2) Do ' rs.Find "[S_NUM]='" & findName & "'" rs.Find rs.Fields(1).name & " Like '20k%'"  ← ここで、サポートしていない旨のエラーが出る。 If Not (rs.EOF) Then Debug.Print rs.Fields(1).Value Else Exit Do End If rs.MoveNext Loop Until rs.EOF '閉じる rs.Close db.Close '終了処理 Set rs = Nothing Set db = Nothing どう直したら、検出結果を取得できますか。 ご教示下さい。

  • ExcelからAccessデータを検索するマクロ

    Excel、Accessとも初心者です。 下記を参考にさせて頂いております。 http://okwave.jp/qa/q441987.html これを、(1)~(3)に対応させたいのですが どのように書き換えればよろしいのでしょうか? (1)A1→ A列の最後まで (2)対応するレコードフィールド2   → 規定した複数のレコードフィールド     (例えば、フィールド3とフィールド5とフィールド8) (3)Excel, Accessともに2007です。 (4)検索の経過は表示させない  (少しでも早く処理したい。ひとつひとつ検索結果を表示すると遅くなると聞ききました) ・・・・・・・・・・・・・・・・・・・・・・・・・ Sub Macro1() Dim db As DAO.Database Dim rs As DAO.Recordset Set db = OpenDatabase("c:\abc.mdb") Set rs = db.OpenRecordset("tbl_a", dbOpenDynaset) rs.FindFirst "[フィールド1]='" & Range("A1").Value & "'" If rs.NoMatch Then   Range("B1").Value = "" Else   Range("B1").Value = rs![フィールド2] End If rs.Close Set rs = Nothing Set db = Nothing End Sub ・・・・・・・・・・・・・・・・・・・・・・・・・ よろしくご教授お願いします。

  • エクセル側からアクセスへデータ転送

    エクセル側からアクセスへデータを転送したく、 Sub Data_Add() Dim db As New ADODB.Connection Dim Rs As New ADODB.Recordset db.Open _ "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=C:\Users\Owner\Desktop\A.mdb;" Rs.Open "B", db, adOpenStatic, adLockPessimistic Rs.AddNew Rs!a = Worksheets("1").Range("A1").Value Rs!b = Worksheets("1").Range("B1").Value Rs!c = Worksheets("1").Range("C1").Value Rs!d = Worksheets("1").Range("D1").Value Rs!e = Worksheets("1").Range("E1").Value Rs.Update Rs.Close db.Close これで、エクセルからアクセス"A"のテーブル"B"のフィールド"a"にエクセルの"A1"を、フィールド"b"にエクセルの"B1"をという風に、セル1つづつを転送させる事はできましたが、セル1つづつでは無く、A列をフィールド"a"に、B列をフィールド"b"にという風に、列ごと追加するにはどの様にしたらいいですか? 又、追加ではなく更新(すでにあったデータに追加するのではなく、上書き)するにはどの様にしたらいいですか? 追加、更新それぞれしたいので、誰か教えて頂けませんか? よろしくお願いします。

  • 【エクセルVBA】DBのデータをCSVに

    VBA初級者です。 oracleDBのデータをCSVへ出力するマクロをVBAで作成中ですが、実装方法が分からず困っています。 ・DB接続はoo4o ・エクセルは2010 ・SQLで取得したデータを1レコードづつCSVに書き出したい ・カラム名をヘッダーとして書き出したい 以下のような実現方法でできるか…?と考えたものの、 肝心のマクロ(VBA)でのDBデータの取得⇒CSVへの書き込み方法がいくら調べてもわかりません。 CSVからDBへのインポートはたくさんあったのですが…。 そもそも取得したレコードを配列で保持して書き出す、という考え方が合っているのか?ヘッダー(カラム名)はどのように書き出せばいいか? など疑問が尽きません。何卒お力添え頂ければ幸いです。 --ボタンクリック時のアクション-- (1)変数定義 (2)DB接続情報確認 (3)DB接続 'DB接続 Set oraSession = CreateObject("OracleInProcServer.XOraSession") Set oraDatabase = oraSession.OpenDatabase(dbSid, dbUser & "/" & dbPass, ORADB_DEFAULT) (4)書き込み用のCSVファイルを作る (5)SQLを実行し返ってきた結果をsplit関数で配列としてwriteListにAddする (5)作成したCSVファイル内にwriteListのデータをPrint #で書き出す (6)完了メッセージを表示 MsgBox "完了しました " (7)DBの切断 'DBクローズ Set oraDatabase = Nothing Set oraSession = Nothing --SQLを実行するメソッド-- (8)SQLを記述、SELECT結果を(5)に返す 恐れ入りますがよろしくお願いいたします。

  • Excel VBAデータ登録のスピードアップしたい

    下記のようなコードがあります。 ■input データ閲覧・登録・編集シート ■data データを格納するシート inputシートとdataシートでdataの受け渡しを行っているのですが、データレコードを切り替えるだけで20秒ちょっとかかるため、作業効率が悪いです。 この時間を1~2秒ぐらいまで減らすには、どのように修正すれば、いいでしょうか?どうかアドバイスをお願いいたします。 Private Sub datatouroku() ’データを登録する Dim touroku As Integer Dim fRange As Range Set fRange = Sheets("data").Columns(1).Find(What:=Range("BC1").Value, _ LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows) touroku = fRange.Row '検索されたNoの行位置を求める Sheets("data").Cells(touroku, 1).Value = Range("BC1:BE1").Value Sheets("data").Cells(touroku, 2).Value = Range("AX1").Value Sheets("data").Cells(touroku, 3).Value = Range("I4").Value   '・・・上記のデータが全部で256件あります。 End Sub ------------------------------------------ Private Sub hyouji() 'データを表示させる Dim fRange As Range Dim kensaku As Long Set fRange = Sheets("data").Columns(1).Find(What:=Range("BC1").Value, _ LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows)    If (fRange Is Nothing) Then '見つからなかった?    MsgBox "入力された顧客コードが存在しません。", vbExclamation    Exit Sub    End If    kensaku = fRange.Row '検索された顧客DCの行位置を求める     Range("BC1:BE1").Value = Sheets("data").Cells(kensaku, 1).Value     Range("AX1").Value = Sheets("data").Cells(kensaku, 2).Value    Range("I4").Value = Sheets("data").Cells(kensaku, 3).Value     '・・・上記のデータが全部で256件あります。 Set trg = Sheets("data").Cells(kensaku, 1) End Sub

専門家に質問してみよう