• ベストアンサー

【VBA】レコードセットからグラフを作成

Excel2002とAccess2002を使っています。 (1)Accessから取得したレコードセットをデータソースにして  グラフを作成する事はできますでしょうか?  (シートにレコードセットを格納せずに) (2)上記が実現不可なら、レコードセットを配列に代入し、  その配列をデータソースにしてグラフを作成する事はできますでしょうか? レコードセットを一度シートに吐き出す事は考えていません。 (1)、(2)とも具体的なコードを書いて頂けると助かります。 よろしくお願いします。

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

  • ベストアンサー
  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.7

#6の対策を取る前は、質問者様が補足に書かれた様な状況でした。 このとき名前"Date"の内容は、下記の様なものでした。文字列として入っています。 ={"1/1/2010";"1/2/2010";"1/3/2010";"1/4/2010";"1/5/2010";"1/6/2010";"1/7/2010";"1/8/2010";(以下略) やむを得ず、倍精度浮動小数点数に変換した後は、下記の様な形でした。 ={40179;40180;40181;40182;40183;40184;40185;40186;40187;4(以下略) この状態で、軸の書式を日付形式にすると、所期の日付で表示されました。 当方xl2000(xl2010は検証用にしか使えていない-使いこなしていない)ですが、下記コードで日付表示されております。 Sub test() Dim cn As ADODB.Connection Dim rs As ADODB.Recordset Dim SQL As String Dim chart1 As Chart Dim i As Long Dim arrayX As Variant Dim arrayY As Variant Set cn = New ADODB.Connection cn.Provider = "Microsoft.Jet.OLEDB.4.0" cn.Open ThisWorkbook.Path & "\db1.mdb" SQL = "SELECT TOP 1000 * FROM Table1 ORDER BY ID;" Set rs = New ADODB.Recordset rs.CursorLocation = adUseClient rs.Open SQL, cn, adOpenStatic, adLockReadOnly With Worksheets(1) arrayX = .Range(.Cells(1), .Cells(rs.RecordCount, 1)) arrayY = .Range(.Cells(1), .Cells(rs.RecordCount, 1)) End With For i = 1 To rs.RecordCount arrayX(i, 1) = CDbl(rs.Fields(1)) arrayY(i, 1) = rs.Fields(2) rs.MoveNext Next i ThisWorkbook.Names.Add Name:="Date", RefersTo:=arrayX ThisWorkbook.Names.Add Name:="Rate", RefersTo:=arrayY Set chart1 = Charts.Add(Before:=ActiveSheet) chart1.ChartType = xlXYScatter chart1.SeriesCollection.NewSeries With chart1.SeriesCollection(1) .XValues = "='" & ThisWorkbook.Name & "'!Date" .Values = "='" & ThisWorkbook.Name & "'!Rate" End With chart1.Axes(xlCategory).TickLabels.NumberFormatLocal = "yyyy/m/d" Set rs = Nothing Set cn = Nothing End Sub

matthew_mu
質問者

お礼

mitarashi様 勘違いしていました!申し訳ございません… >>arrayX(i, 1) = CDbl(rs.Fields(1)) 'ここでDatevalueにしてもダメ の部分を勘違いしていてスルーしていました… コードにCDblを入れて実行したところ 問題なく期待した日付が出てきました。 この度は最後までお付き合い頂き本当にありがとうございました。 mitarashi様は真のハッカーです。(もちろん良い意味の方の) 私も精進致します。

その他の回答 (6)

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.6

#2~5ですが、また出てくるはめになりました... 出来たことに満足してグラフを眺めていると、なんだか変 X軸が日付になっていない。 色々やってみましたが、 レコードセットから配列に取り込む際に、数値に変換し、 For i = 1 To rs.RecordCount arrayX(i, 1) = CDbl(rs.Fields(1)) 'ここでDatevalueにしてもダメ arrayY(i, 1) = rs.Fields(2) rs.MoveNext Next i グラフの目盛りの表示形式を日付形式にしないと、うまく行かない様です。 chart1.Axes(xlCategory).TickLabels.NumberFormatLocal = "yyyy/m/d" 日付のままだと、「名前」に入れる際に、文字列に変えられてしまうみたいです。 ご参考まで。

matthew_mu
質問者

お礼

mitarashi様 改めてこんなに調べて頂いて本当にありがとうございました。 またお返事が遅くなってしまって申し訳ありません… 書いて頂いたコードを実行してみました。 XValueに日付を入れたのですが、 出来上がったグラフを見てみると 2001年から2010年まで日付が入るグラフが すべて1900年代になってしまっていました… おそらく要素の数がX軸になってしまっているのだと思われます… 配列の行と列を入れ替えたりRedimしてみたり !Dateの後に記号や数字を入れたりしてみましたが 現象変わらずです… もしかしたら私の環境に依存するかもしれません。 mitarashi様の方はどのような感じでしょうか?

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.5

#4です。たびたびすみません。 >動的配列の一次元目をredimする代用、セル値は上書きしてしまう 誤解を招きそうですが、読み込んだセルの値は、後ほどレコードセットの値で上書きしてしまうので、関係ありませんと言いたかったものです。補足させていただきます。

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.4

#2,3です。それでもと思ってやってみました。 Excel固有機能に相当お世話になっておりますが、シートに書き出してはいません... 当然ながら、別のグラフを描くときは、別の範囲名をつけないと、先ののグラフも変わってしまいます。 Sub test() Dim cn As ADODB.Connection Dim rs As ADODB.Recordset Dim SQL As String Dim chart1 As Chart Dim i As Long Dim arrayX As Variant Dim arrayY As Variant Set cn = New ADODB.Connection cn.Provider = "Microsoft.Jet.OLEDB.4.0" cn.Open ThisWorkbook.Path & "\db1.mdb" SQL = "SELECT TOP 1000 * FROM Table1 ORDER BY ID;" Set rs = New ADODB.Recordset rs.CursorLocation = adUseClient rs.Open SQL, cn, adOpenStatic, adLockReadOnly '動的配列の一次元目をredimする代用、セル値は上書きしてしまう With Worksheets(1) arrayX = .Range(.Cells(1), .Cells(rs.RecordCount, 1)) arrayY = .Range(.Cells(1), .Cells(rs.RecordCount, 1)) End With For i = 1 To rs.RecordCount arrayX(i, 1) = rs.Fields(1) arrayY(i, 1) = rs.Fields(2) rs.MoveNext Next i ThisWorkbook.Names.Add Name:="Date", RefersTo:=arrayX ThisWorkbook.Names.Add Name:="Rate", RefersTo:=arrayY Set chart1 = Charts.Add(Before:=ActiveSheet) chart1.ChartType = xlXYScatter chart1.SeriesCollection.NewSeries With chart1.SeriesCollection(1) .XValues = "='" & ThisWorkbook.Name & "'!Date" .Values = "='" & ThisWorkbook.Name & "'!Rate" End With Set rs = Nothing Set cn = Nothing End Sub

参考URL:
http://blogs.yahoo.co.jp/mikezang/59251225.html
  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.3

#2です。 まず、GetRowsは100レコード以上はダメな様です。 http://support.microsoft.com/kb/198528/en-us/ (機械翻訳の日本語版は英語以上に訳が分かりませんでした) それではと、下記のコードでやってみましたが、別の制限がある様です。 http://blogs.yahoo.co.jp/mikezang/59251225.html http://okwave.jp/qa/q4398916.html 下記コードのTOP 20のところをいろいろ振ってみましたが、 Excel2000は21からエラーになりました。 Excel2010は、999でもエラーになりませんでした。(1000個のつもりが一個足りなかった) 互換モードではなく、形式を変換した後の話です。 参考URLにある、SEREIS formula 256文字の制限(256列の制限を反映)は妥当な様です。 二つめの参考URLのコード4はメモリー上でやっている様ですが、 ここまで頑張ってメモリー上でやる必要があるのかな?と思います。 なお、Application.Transpose等も試してみましたが、ダメでした。 Sub test() Dim cn As ADODB.Connection Dim rs As ADODB.Recordset Dim SQL As String Dim chart1 As Chart Dim i As Long Dim arrayX() As Date Dim arrayY() As Double Set cn = New ADODB.Connection cn.Provider = "Microsoft.Jet.OLEDB.4.0" cn.Open ThisWorkbook.Path & "\db1.mdb" SQL = "SELECT TOP 20 * FROM Table1 ORDER BY ID;" Set rs = New ADODB.Recordset rs.CursorLocation = adUseClient rs.Open SQL, cn, adOpenStatic, adLockReadOnly ReDim arrayX(rs.RecordCount - 1) ReDim arrayY(rs.RecordCount - 1) For i = 0 To rs.RecordCount - 1 arrayX(i) = rs.Fields(1) arrayY(i) = rs.Fields(2) rs.MoveNext Next i Set chart1 = Charts.Add(Before:=ActiveSheet) chart1.ChartType = xlXYScatter chart1.SeriesCollection.NewSeries With chart1.SeriesCollection(1) .XValues = arrayX .Values = arrayY End With Set rs = Nothing Set cn = Nothing End Sub

matthew_mu
質問者

お礼

こんなに調べて頂き本当にありがとうございますm(_ _)m とてもお手数お掛けしてしまい非常に恐縮です… 私の方で今時間があまり取れない状態なので 恐れながらまた改めて書き込みさせて頂きます。

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.2

#1さんの仰る通りで、エクセルを使いながら、メモリ上に拘る意味が解りかねますが、 興味のおもむくまま調べてみました。一つ利口になりました。 エクセルからmdbにアクセスしています。 'ADOに参照設定要 Sub test() Dim cn As ADODB.Connection Dim rs As ADODB.Recordset Dim SQL As String Dim chart1 As Chart Set cn = New ADODB.Connection cn.Provider = "Microsoft.Jet.OLEDB.4.0" cn.Open ThisWorkbook.Path & "\db1.mdb" SQL = "SELECT * FROM Table1;" Set rs = New ADODB.Recordset rs.Open SQL, cn, adOpenStatic, adLockReadOnly If rs.BOF Then Exit Sub Set chart1 = Charts.Add(Before:=ActiveSheet) chart1.SeriesCollection.NewSeries '試験用データTable1のFields(0)はIDなので、Fields(1)から指定しています With chart1.SeriesCollection(1) .XValues = rs.GetRows(, , rs.Fields(1)) rs.MoveFirst .Values = rs.GetRows(, , rs.Fields(2)) End With Set rs = Nothing Set cn = Nothing End Sub

matthew_mu
質問者

補足

回答ありがとうございます。 メモリ上に拘る理由は、メモリ上で処理できれば シートに書き出す必要がないのでは、、というただの好奇心です。 書いた頂いたコードを実行してみましたところ ずっとエラーが出て悩んでいたのですが、 どうやらレコードセットの行数に関係していたようです。 100件以上のレコードセットで試してみたところ .Values = rs.GetRows(, , rs.Fields(2))の行で 実行時エラー 1004 アプリケーション定義またはオブジェクト定義のエラーです というエラーが出ます。 (たまに違うエラーも出たような…) 4件のレコードセットで試してみたところ、 問題なく実行できました。 実は作りたいグラフが100件以上のレコードを持つ X軸に日付が入り、Y軸に4種のDoubleが入るものでして… (ちなみにテストしたのはまた別のテーブルです…) 100件以上のデータも問題なく実行するにはどうしたら良いでしょうか…?m(_ _)m

回答No.1

こんにちは。 なぜシートにデータを吐き出してはいけないのか、 その理由を明確にすべきでしょう。 単に自分の希望を言うだけではだめです。 あなたの努力は? って言われます。 VBAで行うなら一度シートにデータを吐き出したって 何の問題もないはずです。 グラフだけ作って画像で固定してあとは もとになったシートをさっさと消してしまう ってことはできないでしょうか? 当方、コードを書くつもりは毛頭ありません。 コードもらいならそれに答えるつもりはありません。

関連するQ&A

  • EXCEL2010 VBA グラフの作成

    EXCEL2010のVBAで自動でグラフを作成するコードを作成したいと思っています。 シート1のA1:A10にデータが入っていて、ボタンを押すとコードが実行されて A1:A5までが系列1 A6:A10までが系列2 として表示される折れ線グラフを作成しようと思っています。 さらに作成したグラフは新規にシートを作成して作成したシートに表示させたいと思います。 このような処理を行いたいのですがVBAを始めたばかりなのでグラフの作成くらいしかまだ 分かっていません。 どなたかこの処理を実現できる良い方法を教えてください。よろしくお願いします。

  • VBAで複数のCSVからレコードセットを作りたい

    D:\DATA\ORDER\SOURCE.CSVに売上のデータがあり、 D:\DATA\STOCK\SOURCE.CSVに在庫のデータがあります。 売上には 注文NO,売上日,売上額,在庫NO 在庫には 在庫NO,仕入日,仕入額 とあるとして 在庫.在庫NO,利益,滞留日数,売上.注文NOというような、2つのCSVを結合した結果をADOでレコードセットに格納したい場合どのようなソースになるのでしょうか? 一つのCSVからレコードセットに結果を格納するやりかたならネットに多々掲載されてますが、複数のCSVについてのやり方の掲載が探せなかったので質問します。

  • レコードセットからレコードセットって作れますか?

    WindowsXP,VB6,SP5,で開発しています。 タイトルそのままなのですが、 ある事情で、まずはデータベース(Access)からレコードセットを作成しています。 そのレコードセットをもとに色々と抽出したいんです。 もし、データベースからSQL文で抽出するときみたいに、そのレコードセットを、 SUM(~とかGROUP化したりとかできればいいなあと思っているのですが、 その方法がわからず、2,3回遠回りしてレコードセットを作成してます。 レコードセットからレコードセットを作成することってできないのでしょうか? わかりにくくてすみませんが、どうぞよろしくお願いしますm(_ _)m

  • Excelでの複数のシート間のグラフ作成

    Excel2002及び2003で複数のシートでグラフ作成の仕方を教えていただけないでしょうか。 例えば、Sheet1の表とSheet2の表のデータを基にSheet3にグラフを作成したいのです。 確かに、Sheet3にSheet1とSheet2のグラフをまとめた表を作成すれば、簡単にできるのですが、 データ量が多いためにまとめるのが困難です。 また、応用として、ブック間のデータを基にグラフを 作成できるのでしょうか。 よろしくお願いします。

  • レコードセットの中身を配列に、そしてワークシートに。

    今excel2003のVBEで外部データベースから店舗別の売上データを取得し それをエクセルのワークシートに出力するというプログラムを作成しています。 ここで問題なのが扱うデータの量が多すぎでレコードセット検索を 使用してそれをDo Until RS.EOFで各店舗の日別売上に出力していくとものすごく時間がかかってしまいます。 そのため配列を使う方法を見つけたのですが配列を使ったことなくて どうしたらよいのかわかりません。 なんとかレコードセットの中身を配列に格納後にそれを一気に範囲貼り付けしたいと思います。 でも配列内で売上表のフォーマットに整形を行うことができるのでしょうか? レコードセットのフィールドは店舗別日別売上、売上日付、店舗コード、ブランドセクションです。 売上日付|ブランドセクション|店舗コード|店舗別日別売上 20100201      100     1001     100000 20100201      100     1002     10000 ・          ・      ・      ・ ・          ・      ・      ・  売上表のフォーマットは縦列に1から月末までの日にち、横行に各店舗名が並んでいて各店舗の日別売上が一目でわかるつくりになっています。 各店舗名の上に店舗コードを持たせてそれを元に入力列を取得するという方法も考えたのですがそれも効率的とは思えません。 なにか良い方法はないでしょうか? アドバイスお願いします。 最後に文章だけの説明でわかりにくくてすみません。 よろしくおねがいします。

  • レコードセットについて

    ACCESSを勉強中のものです。 レコードセットの意味がよくわからないのですが テーブルやクエリの事を「レコードセット」と言うのでしょうか?

  • Excel2007でグラフを自動作成させる

    Excel2007で、同じようなデータセットが複数ある時に、 まず、1つのデータセットで普通に(手動で)グラフ(グラフA)を作成し、 そのあと、残りのデータセットで、グラフAと同じ設定で複数のグラフを自動で作らせることは 可能でしょうか? わかりにくければ補足説明いたしますので、 よろしくお願いいたします。

  • VBAでGANTのグラフを作成したい

    office365 ①GANT_DATAシートに計画と実績のGANTデータ ②GANTシートにガントのグラフを表示 したいです。 ①を元に②のグラフを自動で作成したい ガント表示させる構成は kotei1からkotei6までの計画開始計画終了実績開始実績終了の日時データがあり、Serial1からSerial2,Serial3とGANT_DATAのA列でデータがなくなるまでのガントグラフを表示。 Serialは+30行毎に計画と実績データをデータベースから持ってくる構成。 現状は、GANTシートにひな形としてのグラフを用意しておき、 データ範囲等を1ケ1ケグラフへ反映させてガントのグラフを表示させています。 下記のイメージです。 GANTシートでのSerial1のグラフは グラフデータの範囲:=GANT_DATA!$A$9:$C$20 系列1の系列値:=GANT_DATA!$B$9:$B$20 系列2の系列値:=GANT_DATA!$C$9:$C$20 軸ラベルの範囲:=GANT_DATA!$A$9:$A$20 GANTシートでのSerial2のグラフは グラフデータの範囲:=GANT_DATA!$A$39:$C$50 系列1の系列値:=GANT_DATA!$B$39:$B$50 系列2の系列値:=GANT_DATA!$C$39:$C$50 軸ラベルの範囲:=GANT_DATA!$A$39:$A$50 の様にガントシートのデータ範囲を設定しておき、 GANT_DATAへデータをデータベースから持ってきたらガントのグラフが表示できる構成にしているのですが、グラフの数が増えると上記データ範囲の設定をするのも大変なので、①のシートから②のガントグラフを自動で作成できる様にしたいです。 VBAベタで教えていただきたくよろしくお願いします。 グラフの軸設定はなんとかなると思うので、根本のグラフ表示部分を作成する構成を教えていただけたらと思います ※ GANTグラフには工程間に細く青い線をしきりで入れてます。 これも実現化であれば教えていただきたく。 現状は実線をグラフへコピペで貼り付けています。

  • レコードセットとデータセットの違い

    こんにちは。Access VBAの本を読んでいたらデータはレコードセットで取得すると書いてあります。 ネットで.NETの記事を読んでいたらデータはデータセットで取得と書いてありました。 このレコードセット、データセットの違いは平たく言うとなんでしょうか? 私はAccess VBAが少しわかる程度のレベルです。

  • MS-Accessで1レコード単位のデータをグラフ化するには?

    お忙しいところ恐縮です。 Accessで保存してあるデータからグラフを作成したいのですが、どうもそのやり方が分からず困っています。 ちょっとうまく説明できないかもしれませんが、フォーム(またはレポート)にグラフオブジェクトを貼り付けて、表示させたいテーブルをリンクさせると、項目ごとに全データをグラフ化してしまいます。しかしそれでは実現したいグラフではなく、欲しいのはレコード単位でそのレコードの項目それぞれをグラフ化したものです。 以下に例を記載します。 個人ごとに各科目の成績(得点)が格納されたテーブルです。 これを個人ごとに科目を軸としたレーダーチャートにて表示するようなグラフです。 データはこんな感じです。  氏名 |国語|数学|理科|社会|英語|音楽|体育|美術・・・・ -------------------------------------------------------------------  安室波平| 80 | 75  | 82 | 68  | 42  | 63  | 74  | 58  井上晴美| 77 | 61  | 77 | 66  | 81  | 55  | 65  | 88  上田洋介| 67 | 68  | 77 | 78  | 57  | 45  | 66  | 74  江田吾郎| 71 | 34  | 55 | 60  | 42  | 73  | 64  | 74  太田真由| 81 | 88  | 64 | 98  | 55  | 85  | 74  | 66  ・・・・・・・ ・・・・・・ ・・・・ ・ これらを各個人ごとに1ページ(1画面)で、科目の得点を放射線状の軸に取りたいと思ってます。 ネットなどのサンプルで探しても、「縦軸に得点、横軸に個人、科目ごとの折れ線」のようなグラフはよくありますし、こちらは簡単にできるのですが、1レコードごとにそのフィールドの値でグラフを作るサンプルを見つけることができず困ってます。 Accessの環境はVer2003です。 フォームでの実装でもレポートでも実装でもかまいません。 お手数をおかけして申し訳ありませんが、どうか教えてくださいませ。

専門家に質問してみよう