• ベストアンサー

Accessで縦に情報が展開されてるテーブルの処理

作業環境は以下の通りで、Accessの知識は初心者です。 OS:Windws7/使用ソフト:Access2003 やりたい事はこれに近いのですが、もう一ひねりある為困っています。 http://okwave.jp/qa/q2452277.html?from=recommend テーブルに以下のようなデータがあります。 薬剤/配番/効果/使用方法 A剤/00001/頭痛/1回1錠 A剤/00002/発熱/食後…(長文) B剤/00001/頭痛/1回2錠 B剤/00003/裂傷/清潔な手で…(長文) これを薬剤名ごとに、効果(数は120を超えます)と使用方法を横へ並べる事はできますか?

この投稿のマルチメディアは削除されているためご覧いただけません。

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

  • ベストアンサー
  • 30246kiku
  • ベストアンサー率73% (370/504)
回答No.12

#9です > 実行時エラー'94': > Nullの使い方が不正です > > デバックボタンを押してみると55行目の↓この部分が黄色く反転されました。 > sA(i * 2 - 1) = rs("効果") おそらく、「効果」にデータが無くて Null になっていると思われます。 ※ データ/テーブル内容からすると、何かしら設定されているものと思っていたんですが・・・ 対処方法は2つあって、 1)代入する時に Nz 関数を使って Null を ""(空文字)に置換える >    sA(i * 2 - 1) = rs("効果") >    sA(i * 2) = rs("使用方法") ↓     sA(i * 2 - 1) = Nz(rs("効果"))     sA(i * 2) = Nz(rs("使用方法")) ただ、これには問題がありそう というのは、両方値が入っていなければ良いと思いますが、 どちらか一方だけに値が設定されていたら・・・ 変な内容に? 2)必ず「効果」「使用方法」両方に値が設定されているものを対象にする >  Const CSQL1 As String = "SELECT DISTINCT 配番 FROM {%1};" >  Const CSQL2 As String = "SELECT * FROM {%1} ORDER BY 薬剤;" これで抽出しているわけですが、 条件として「効果」「使用方法」とも設定されているもの・・・ を、追加します。  Const CSQL1 As String = "SELECT DISTINCT 配番 FROM {%1} " _    & "WHERE 効果 Is Not Null AND 使用方法 Is Not Null;"  Const CSQL2 As String = "SELECT * FROM {%1} " _    & "WHERE 効果 Is Not Null AND 使用方法 Is Not Null ORDER BY 薬剤;" これに変更すると、1)での変更は不要です。 けど、念のために1)も適用しておいた方が良いかも この修正でどうなりますでしょうか

lotus2014
質問者

お礼

回答ありがとうございます。 > おそらく、「効果」にデータが無くて Null になっていると思われます。 確認してみたところ確かにNull値がありました。 選択クエリで効果と使用方法と両方の3タイプにIs Nullで抽出をかけたところ、効果のみNull値が存在するようです。 その為、2)に変更してみたところ、希望通り横に展開されました!! ありがとうございます。 処理の解説も頂いていましたので、落ち着いたら本格的にAccessの勉強を始めたいと思います。 (排出されたCSVをもう一加工する為に他のソフトとの連携設定を考えなくてはならないのです…)

その他の回答 (14)

  • 30246kiku
  • ベストアンサー率73% (370/504)
回答No.15

#14です 結果を教えていただき、ありがとうございます > 単純に入力忘れと思われます > Nullの配番は様々という事になります 手間を取らせてしまった様で、すみません。 心配性なもので・・・ 効果 Null は継続用途? と疑ったわけですが、 継続のやり方は、 ・#14での、配番+1 とする方法のほかに、 ・同じ薬剤に、同じ配番を存在させ、薬剤を昇順、配番を昇順、効果を降順で並ばせる が考えられたので、効果 Null の配番も合わせて調べられたら・・・・ と記述したつもりでした (そう伝わっていなかったら、ごめんなさい) でも、 > 単純に入力忘れと思われます であれば、#14 の VBA は忘れてください。 また、#12の2)は、効果 Null のものを除外していますが、 同じ配番で、例えば、効果が「注意」「ご注意」 Null のものは、 同じ項目「効果xx」で縦に並ぶので、何箇所かが空欄になっていても 前後関係で理解できる?ものなのかと・・・ であれば、2)ではなく、1)の方が良かったりして・・・ ・効果 Null のものは除外する ・使用方法だけでも盛り込む これは、質問者さんの判断になるかと思います。 なお、#12の2)での > AND 使用方法 Is Not Null 部分は削除しても良いかも 余談) 他ご質問への#12を使った展開は、 ・配番の順で記述位置を管理するのは同じ。 ただし、見出しに使う文字列は、同一配番での効果の一番短い物を使うとか 同一配番で、例えば、効果が「注意」「ご注意」なら「注意」の方を見出しに とでもすれば、列数は今回のものの半分程度になるかと・・・ ※ 「注意」「ご注意」を別々の列にしようとするから、2000 項目以上になるのかも ※ 単に文字列として見出しを作る事は出来ますが > 効果(230文字程度、全角文字と半角英数字と-./()・などの記号が含まれる) より、 他システムが見出しとして解釈できない文字を編集する必要があると思います。 (問題なければ編集は不要ですけど・・・:心配性なもので・・・) 以上 失礼しました

lotus2014
質問者

お礼

こんにちは。 1)の方法での処理はこんな感じになりました。 レコード:455531 処理時間:10分 CSVサイズ:169MB CSV行数:108012 空欄を含めた事で10フィールド程増えた為、時間とCSVサイズが少し増えたようです。 覚えるのは容易ではなさそうですがAccessの基本が理解できたらVBAも勉強しようと思います。 この度は本当にありがとうございました。

lotus2014
質問者

補足

回答ありがとうございます。 > 同じ薬剤に、同じ配番を存在させ、薬剤を昇順、配番を昇順、効果を降順で並ばせる なるほど、そんな方法もあったのですね。 全然気づかずすみませんでした… > これは、質問者さんの判断になるかと思います。 はい、前後関係で理解できるものもあります。 その為、1)の方法で問題ない事がわかりました。 数も50個程度なので私の判断で適宜埋めてしまっても大した労力もなさそうですが… > ただし、見出しに使う文字列は、同一配番での効果の一番短い物を使うとか そんなことも調整できるのですね! そういった例は複数見かけました。 また今日気づいたのですが、配番は違うけど効果が重複してしまっているものなどありました。 > 他システムが見出しとして解釈できない文字を編集する必要があると思います。 説明欄の入力場所はこれらの記号が問題なく入るので、編集する手間は省けそうです^^ 折角修正して頂いたのに、情報後出しになってしまったりでお手間をとらせてしまい申し訳ございません。 説明してもらってやっと気づくなんてAccess知識がない云々のレベルじゃないですね>< 明日にでも1)の方法の結果などご報告いたしますね!

  • 30246kiku
  • ベストアンサー率73% (370/504)
回答No.14

#12です > 効果のみNull値が存在するようです これ、結構引っ掛かってました。 #12での対処は安易だったかもしれません。 > 使用方法フィールドはメモ型 これを一旦疑う方向で考えてみると・・・ インポートする前のテキストファイル内の使用方法は、 ある程度の文字数で区切られていて・・・ 継続する為に、例えば、配番を+1して、効果を Null また、使用方法には続きを・・・ こう考えてみると、効果 Null の役割はあるのかな? ※※ 何故、効果の Null が存在するのか確認してください ※※ ※ また、効果が Null の配番は何?は、調べておいた方が良いと思います もしそうであれば、インポートした後に 使用方法を繋げて、効果 Null のものは削除するとか必要だったのかも・・・ 現状のデータ状態で、上記の使用方法継続と考えた記述は以下になりますが、 上記推測で文字数で区切ったのには理由があると思うので確認は必須です。 なお、上記推測での使用方法継続を捨てるのなら、#12のままでも #9からの変更点は、 ・配番の順で記述位置を決定する時には、効果が Null じゃないもので ・記述位置を求める際 効果が Null じゃなかったら、それ用の記述位置を求める 効果が Null だったら、前回の位置に これ用に、変数 iPos もちろん、効果 Null の出現位置は、配番順と仮定するので ORDER BY 薬剤, 配番 として、配番の昇順も指定する様に 継続の使用方法は、配番+1と仮定していましたが、これが外れた場合 順を特定できないので、最悪の場合だけ処理する様に (配番に -1 が存在するみたいで、何の用途か不明) (配番は正と、勝手に思い込んでいたので) Public Function Samp2()   Dim dic As Object   Dim rs As DAO.Recordset   Dim sA() As String   Dim sSql As String   Dim vSave As Variant   Dim iPos As Long, i As Long   Dim ffn As Integer   Const CTABLE As String = "テーブル名" ' ← 変更要 ★   Const CFILE As String = "\testSamp1.csv" ' ← 変更要 ★   Const CSQL1 As String = "SELECT DISTINCT 配番 FROM {%1} " _               & "WHERE 効果 Is Not Null;"   Const CSQL2 As String = "SELECT * FROM {%1} ORDER BY 薬剤, 配番;"   Set dic = CreateObject("Scripting.Dictionary")   sSql = Replace(CSQL1, "{%1}", CTABLE)   Set rs = CurrentDb.OpenRecordset(sSql)   While (Not rs.EOF)     dic(rs("配番").Value) = rs.AbsolutePosition + 1     rs.MoveNext   Wend   rs.Close   Set rs = Nothing   ReDim sA(dic.Count * 2)   ffn = FreeFile()   Open CurrentProject.Path & CFILE For Output As #ffn   sA(0) = "薬剤"   For i = 1 To dic.Count     sA(i * 2 - 1) = "効果" & i     sA(i * 2) = "使用方法" & i   Next   Print #ffn, Join(sA, ",")   For i = 0 To UBound(sA)     sA(i) = ""   Next   sSql = Replace(CSQL2, "{%1}", CTABLE)   Set rs = CurrentDb.OpenRecordset(sSql)   While (Not rs.EOF)     If (vSave <> rs("薬剤").Value) Then       If (Not IsEmpty(vSave)) Then         For i = 0 To UBound(sA) - 1           Write #ffn, sA(i),           sA(i) = ""         Next         Write #ffn, sA(i)         sA(i) = ""       End If       vSave = rs("薬剤").Value       sA(0) = vSave       iPos = 0     End If     If (Not IsNull(rs("効果"))) Then iPos = dic(rs("配番").Value)     If (iPos > 0) Then       i = iPos * 2       sA(i - 1) = sA(i - 1) & rs("効果")       sA(i) = sA(i) & rs("使用方法")     End If     rs.MoveNext   Wend   If (Len(sA(0)) > 0) Then     For i = 0 To UBound(sA) - 1       Write #ffn, sA(i),     Next     Write #ffn, sA(i)   End If   Close #ffn   rs.Close: Set rs = Nothing   Set dic = Nothing End Function ※ 処理速度がどの程度だったのか気になります。 よろしければ、どの位・・・ 教えていただければと思います。 レコード:何件、CSV行数:何行、サイズ、何分位・・・とか

lotus2014
質問者

お礼

遅くなりまして申し訳ございません。 元のテキストファイルを仮に「説明.txt」とします。 「説明.txt」はホームページ上の薬剤の説明欄へ入力する情報が入っております。 【説明.txt】 薬剤(8文字の半角英数字の組み合わせ) 配番(1桁のマイナスの値から1000程度の値までの数字) 効果(230文字程度、全角文字と半角英数字と-./()・などの記号が含まれる) 使用方法(最大2500文字程度で、全角文字と半角英数字と-./()・,などの記号が含まれる) > こう考えてみると、効果 Null の役割はあるのかな? > ※※ 何故、効果の Null が存在するのか確認してください ※※ > ※ また、効果が Null の配番は何?は、調べておいた方が良いと思います 「説明.txt」を開いて確認してみましたところ、該当薬剤の効果がタブになってますので、単純に入力忘れと思われます。 その為、Nullの配番は様々という事になります。 と、申し上げますのも配番は説明欄の中での表示順位です。 配番=効果でもあります。その為、効果名が多少違くても同じ意味合いのものは配番が一致します。(実際そういうものもあります)そして配番にはNullが存在しません。 なぜマイナスの値があるのかについては当初、1の情報を1番上に表示させたかったが、それよりも重要な情報が出てきた為マイナスの値を作るようになった為のようです。 > よろしければ、どの位・・・ 教えていただければと思います。 これは#12での処理の事になりますが レコード:455531 処理時間:5分未満 CSVサイズ:166MB CSV行数:108012

lotus2014
質問者

補足

すみません、自社のデータでは無いのと参照URLに沿ってしまった為、重要な情報が抜けてしまった事で2度手間になってしまいましたね… null値がなぜ存在したか考えてもいませんでした。 恐らく、使用方法にカンマが存在してるからかもしれません。 その他の情報として、使用方法はメモ型で2500字以内に収まる内容です。 現在自宅の為、確かな事は申し上げられませんので、明日にでも他含めて正しい情報に修正します。 そして回答12のVBAですが、レコード数108012、5分未満で処理は終了しました。 csvの行数とサイズは明日、確認しますね。

回答No.13

なるほど・・・。 原因を究明したいところですが、#9さんの回答でバッチリのようですので これは私の個人的な宿題とさせていただきます。 つたない回答にお付き合いいただきましたこと恐縮です。

lotus2014
質問者

お礼

いいえ、こちらこそ画面上のやり取りだけで言わんとした事を組み立て、形にするべく試行錯誤して頂いてお礼申し上げます。 HTMLをかじった私の話ですが、人様が書いて下さったコードを見て、触るのは本当に勉強になりました。(今もなおのことですが) どこまで極められるのかわかりませんが、いづれ私もこの2つのVBAを読み返して、懐かしく思える日がくる事を楽しみに勉強を始めようと思います^^

回答No.11

処理速度はかなり改善していると思いますが未検証です。 メモリ不足でパンクするかも? ※成否に関わらず結果(エラーメッセージになるかも?)を教えてください。 前回の関数を下記に差し替えてください。 では。 Function JoinCSV() '要参照設定Microsoft ActiveX DataObject Library 2.5以上   Dim Cn As ADODB.Connection   Dim RsK As ADODB.Recordset   Dim RsS As ADODB.Recordset   Dim i As Long, j As Long, k As Long   Dim sSql As String   Dim FF As Integer   Dim RowTmp() As String   Dim csvRows() As String   Const dLim As String = ""","""   Dim csvAll As String      Set Cn = CurrentProject.Connection     Set RsK = New ADODB.Recordset   sSql = "TRANSFORM " _     & "First(Tbl.[効果]) AS 効果の先頭 " _     & "SELECT Tbl.[薬剤] " _     & "FROM Tbl " _     & "GROUP BY Tbl.[薬剤] " _     & "PIVOT '効果' & Tbl.[配番];"   RsK.Open sSql, Cn, adOpenStatic, adLockReadOnly     Set RsS = New ADODB.Recordset   sSql = "TRANSFORM " _     & "First(Tbl.[使用方法]) AS 使用方法の先頭 " _     & "SELECT Tbl.[薬剤] " _     & "FROM Tbl " _     & "GROUP BY Tbl.[薬剤] " _     & "PIVOT '使用方法' & Tbl.[配番];"   RsS.Open sSql, Cn, adOpenStatic, adLockReadOnly     ReDim RowTmp(RsK.Fields.Count * 2 - 2)   ReDim csvRows(RsK.RecordCount)      'ヘッダー取得   For i = 0 To RsK.Fields.Count - 1     RowTmp(j) = RsK.Fields(i).Name     j = j + 1     If j > 1 Then       RowTmp(j) = RsS.Fields(i).Name       j = j + 1     End If   Next   csvRows(0) = Join(RowTmp, ",") '配列をJoinで一行に      '各データ取得   k = 1  ' 0 はヘッダーで使用済み   Do Until RsK.EOF     ReDim RowTmp(RsK.Fields.Count * 2 - 2)     j = 0     For i = 0 To RsK.Fields.Count - 1       RowTmp(j) = IIf(i = 0, """", "") _             & Nz(RsK.Fields(i).Value, "") '最初なら行頭に " を付加       j = j + 1       If j > 1 Then         RowTmp(j) = Nz(RsS.Fields(i).Value, "") _               & IIf(i = (RsK.Fields.Count - 1), """", "") '最後なら行末 " を付加         j = j + 1       End If     Next          csvRows(k) = Join(RowTmp, dLim)     'Debug.Print i, csvRows(k)     k = k + 1     RsK.MoveNext     RsS.MoveNext   Loop   csvAll = Join(csvRows, vbCrLf)   FF = FreeFile   Open CurrentProject.Path & "\JoinCSV.csv" For Output As #FF      Print #FF, csvAll   Close #FF     RsS.Close: Set RsS = Nothing   RsK.Close: Set RsK = Nothing   Cn.Close: Set Cn = Nothing   Msgbox "終了しました" End Function

lotus2014
質問者

補足

回答ありがとうございます。 今回テスト環境では成功し、本番環境ではこのようになりました。 実行時エラー'52': ファイル名または番号が不正です デバックボタンを押してみると75行目の↓この部分が黄色く反転されました。 Print #FF, csvAll そのまま終了し、記録されたところまでのCSVを開いてみると、ヘッダーが途中まで作成されていました。 薬剤/効果-1/使用方法-1/効果10/使用方法10/効果2/使用方法2/効果28/使用方法28/… ※質問の都合上、「配番」としたものは本番環境では不規則な数字が入っている為、このような表示になっています。 ちなみにこの数字は表示される順位の事を指しています。 なお、ヘッダー以外の情報は入っておりませんでした。 私が伝えた情報が不足しているのか、データ量がすごく多いのか、何度もお手数おかけしてすみません。

  • ki073
  • ベストアンサー率77% (491/634)
回答No.10

No.9の30246kikuさんに続いて、横からすみません。 データ量ですが、およそ薬剤11万種類×効果120種類というとなのでしょうか? そうすると1つが100バイトとしても、ファイルサイズで1.3Gバイトかそれ以上となるのでしょうか? 全部読むのはかなり苦しそうですね。A剤が続いていて、それが終わったらB剤になるようにかたまっているのでしたら、順番に読み込んでいって、1薬剤ごとに処理するのが早そうです。(かたまってなければあらかじめソートする) エクセルであらかじめソートするのも大きすぎて無理なのかな?? Accessは全くの素人なのですが、インデックスを設定しているのでしょうか? それともリレーションを設定した時点でインデックスはつくられるのでしょうか?

lotus2014
質問者

補足

回答ありがとうございます。 > データ量ですが、およそ薬剤11万種類×効果120種類 その通りです。 元データはテキストファイルで、それをAccessにインポートしました。 元のテキストファイルは、99.4MBです。 > 順番に読み込んでいって、1薬剤ごとに処理 はい、薬剤ごとに固まっております。 > インデックスを設定しているのでしょうか? 特に設定していませんし、インデックスという言葉も初めて耳にしました。

  • 30246kiku
  • ベストアンサー率73% (370/504)
回答No.9

おじゃまします 記憶だけなのですが、 一気に書き出し・・・は、ソコソコの文字数であれば速くて 大容量になるとかえって遅くなったような気がします。 (嘘を言っているかもしれません) 大量レコードでのクロス集計2発&CSV書出しを クロス集計もどきを自力&1行毎の書き出しにしてみました。 ※ 列の並び順が変わるかも・・・ ★ 部分を変更の上実行してみてください。 Public Function Samp1()   Dim dic As Object   Dim rs As DAO.Recordset   Dim sA() As String   Dim sSql As String   Dim vSave As Variant   Dim i As Long   Dim ffn As Integer   Const CTABLE As String = "テーブル名" ' ← 変更要 ★   Const CFILE As String = "\testSamp1.csv" ' ← 変更要 ★   Const CSQL1 As String = "SELECT DISTINCT 配番 FROM {%1};"   Const CSQL2 As String = "SELECT * FROM {%1} ORDER BY 薬剤;"   Set dic = CreateObject("Scripting.Dictionary")   sSql = Replace(CSQL1, "{%1}", CTABLE)   Set rs = CurrentDb.OpenRecordset(sSql)   While (Not rs.EOF)     dic(rs("配番").Value) = rs.AbsolutePosition + 1     rs.MoveNext   Wend   rs.Close   Set rs = Nothing   ReDim sA(dic.Count * 2)   ffn = FreeFile()   Open CurrentProject.Path & CFILE For Output As #ffn   sA(0) = "薬剤"   For i = 1 To dic.Count     sA(i * 2 - 1) = "効果" & i     sA(i * 2) = "使用方法" & i   Next   Print #ffn, Join(sA, ",")   For i = 0 To UBound(sA)     sA(i) = ""   Next   sSql = Replace(CSQL2, "{%1}", CTABLE)   Set rs = CurrentDb.OpenRecordset(sSql)   While (Not rs.EOF)     If (vSave <> rs("薬剤").Value) Then       If (Not IsEmpty(vSave)) Then         For i = 0 To UBound(sA) - 1           Write #ffn, sA(i),           sA(i) = ""         Next         Write #ffn, sA(i)         sA(i) = ""       End If       vSave = rs("薬剤").Value       sA(0) = vSave     End If     i = dic(rs("配番").Value)     sA(i * 2 - 1) = rs("効果")     sA(i * 2) = rs("使用方法")     rs.MoveNext   Wend   If (Len(sA(0)) > 0) Then     For i = 0 To UBound(sA) - 1       Write #ffn, sA(i),     Next     Write #ffn, sA(i)   End If   Close #ffn   rs.Close: Set rs = Nothing   Set dic = Nothing End Function やっている事は、 ・配番の昇順で、その配番のものは何個目に配置する・・・ これを Dictionary で 1 ~ の連番で管理するようにして ・薬剤順で並べたレコードを順に処理して、 薬剤が変わったら、1行書出し その途中のデータを作り込む配列が sA sA(0) には薬剤、sA(1) には 効果1 、sA(2) には 使用方法1 sA(3) ~ は、添え字奇数部分が効果、偶数部分が使用方法 ヘッダの書き出しでは、"" で囲まないとのことなので sA を ,(カンマ)で繋げたものを Print 以降の行は "" で囲むことから Write (元のデータが文字列なので "" で囲まれる) (逆に "" で囲んでもらいたいので String の配列を利用) ※ 大量データでは確認していないので、遅かったりしたらごめんなさい 余談) 大量のデータを順に処理したい時には DAO を使った方が良さそうです ADO では、全部のデータを用意するまで Open から先に進まないような・・・ DAO では、Open から先に進むまでが速い様な・・・ (私の感覚だけなので、嘘かも)

lotus2014
質問者

お礼

回答ありがとうございます。 処理の解説までしていただいてありがとうございます。 後ほどゆっくり調べてみようと思います。 テーブル名と、CSV名と、マクロのプロシージャ名を変更し、テスト環境では成功したのですが、本番環境だと下記のエラーが返ってきます。 実行時エラー'94': Nullの使い方が不正です デバックボタンを押してみると55行目の↓この部分が黄色く反転されました。 sA(i * 2 - 1) = rs("効果") そのまま終了し、記録されたところまでのCSVを開いてみると、各フィールドと列の並び順は全て希望の通り作成されています。 薬剤/効果1/使用方法1/効果2/使用方法2/…使用方法122 薬剤のそれぞれの情報も、各セルに収まっています。 以上の事から4369行までは正常に情報が処理されたようなのですが、なぜこのエラーが返ってきたのか分かりません。 重ねての質問で大変申し訳ございませんが、どういった事がこのエラーにつながったのかお解かりでしたら教えて頂けないでしょうか。

回答No.8

すみません。 #6のコードの後半の Write #FF ,buf を Print #FF ,buf に修正してください。 これでひとつに収まってしまう問題は解決するハズです。 時間が掛かる件について。 Buf(メモリ)に一旦全て読み込んでから一度にファイルに書き出し・・・ を考えていましたが、11万レコード位になっているとのことですので タスクマネージャーで観察するとメモリを厳しく圧迫しているハズです。 改善策を模索中です。(期待しないでください。) という訳で今晩の回答はお休みさせてください。

lotus2014
質問者

お礼

回答ありがとうございます。 > Print #FF ,buf この1行でファイルにデータを書き出す命令をしてるんですね! こういった操作に関しての宣言や語句(?)はかなり数多くあると思うのですが、全部覚えていらっしゃるのでしょうか? 私は英語など中学生レベルでも怪しいので、プログラミングなどの英語を羅列して処理させる類のものは最初がとっつきにくくて^^; HTMLをかじっているのですが、文法を覚える位で後は便利なものでエディタ上のボタン操作でタグを吐き出してくれます。 多少のタグは何度も使ううちに覚えましたが、VBAはHTMLとは比べ物にならない位難しそうですね… 11万レコードというのはやはり処理が重いのですね。 本来ならば講習を受けたり、業者に依頼する案件のところを、こうして善意で教えて頂き大変感謝しております。 Accessを使いこなせるようになれば、可能性は0でないことが分かっただけでも収穫です^^ 自分でも分かる範囲で試行錯誤してみます!

回答No.7

>3時間かかっても終了せず・・・ 途中で強制終了してしまったということでしょうか? テーブルのレコード数はどれ位でしょう? あと、Q効果クエリを削除していなければ開いて 左下に、レコード位置/総レコード数が表示されますが レコード数が表示されるまでの時間と表示された時のレコード数はどれ位でしょう? Q効果とQ使用方法から中間テーブルを作成してからの方が安全かもしれません。 ただ、私の手に負えないような気がしてきました。。。

lotus2014
質問者

お礼

回答ありがとうございます。 > 途中で強制終了してしまったということでしょうか? いいえ、別の用途でAccessを使用する都合が出来た為、途中でキャンセルしました。 > レコード数が表示されるまでの時間と表示された時のレコード数はどれ位でしょう? 表示時間は30秒かからない程度で、レコード数は108012となっております。 テスト環境(5レコード程度)でJoinCSV.csvとして吐き出された物をCSVエディタで開くと、1セルの中に全ての情報が入っていたのですがその為でしょうか? テキストエディタで開くと薬剤に対して横1行づつ展開したので気にしなかったのですが…

回答No.6

こんな感じかな。例外処理的なモノ、エラー処理が含まれていません。 Accessデータファイルと同じフォルダにJoinCSV.csv が作成されます。 検証は十分に行ってください。 手順。 Alt + F11 でVBEのウィンドウにします。 メニューのツール → 参照設定 を選択。 ライブラリの一覧が出ますので、Access2003なら (Microsoft ActiveX DataObject Library 2.5 以降だと思います) にチェックを入れて、OK で閉じます。 メニュー → 挿入 → 標準モジュール を選択。 新たなウィンドウが出ますので下記コードをコピペ。 メニュー → デバッグ → ○×△のコンパイルを選択。 何も起きなければ OK です。 Ctrl + S でファイルの上書き保存します。 モジュール名を聞いてくるので、適当な名前を付けてください。 Alt + F4 でVBE を閉じます。 『マクロ』の新規作成から アクション に「プロシージャの実行」、 下のプロシージャ名に、JoinCSV() とします。 マクロを適当な名前で保存します。 そのマクロを実行すれば、csv ファイルが出来ます(多分)。 なお、クエリ(Q薬剤・Q効果・Q使用方法)は不要です。 Function JoinCSV() '要参照設定Microsoft ActiveX DataObject Library 2.5以上   Dim Cn As ADODB.Connection   Dim RsK As ADODB.Recordset   Dim RsS As ADODB.Recordset   Dim i As Integer   Dim sSql As String   Dim Buf As String   Dim FF As Integer      Set Cn = CurrentProject.Connection      Set RsK = New ADODB.Recordset   sSql = "TRANSFORM " _     & "First(Tbl.[効果]) AS 効果の先頭 " _     & "SELECT Tbl.[薬剤] " _     & "FROM Tbl " _     & "GROUP BY Tbl.[薬剤] " _     & "PIVOT '効果' & Tbl.[配番];"   RsK.Open sSql, Cn, adOpenStatic, adLockReadOnly      Set RsS = New ADODB.Recordset   sSql = "TRANSFORM " _     & "First(Tbl.[使用方法]) AS 使用方法の先頭 " _     & "SELECT Tbl.[薬剤] " _     & "FROM Tbl " _     & "GROUP BY Tbl.[薬剤] " _     & "PIVOT '使用方法' & Tbl.[配番];"   RsS.Open sSql, Cn, adOpenStatic, adLockReadOnly      For i = 1 To RsK.Fields.Count     Buf = Buf & RsK.Fields(i - 1).Name & ","     If i > 1 Then       Buf = Buf & RsS.Fields(i - 1).Name & ","     End If   Next   Buf = Left(Buf, Len(Buf) - 1)      Do Until RsK.EOF     Buf = Buf & vbCrLf     For i = 1 To RsK.Fields.Count       Buf = Buf & """" & RsK.Fields(i - 1).Value & """" & ","       If i > 1 Then         Buf = Buf & """" & RsS.Fields(i - 1).Value & """" & ","       End If     Next          Buf = Left(Buf, Len(Buf) - 1)     RsK.MoveNext     RsS.MoveNext   Loop   FF = FreeFile   Open CurrentProject.Path & "\JoinCSV.csv" For Output As #FF   Write #FF, Buf   Close #FF      RsS.Close: Set RsS = Nothing   RsK.Close: Set RsK = Nothing   Cn.Close: Set Cn = Nothing   Msgbox "終了しました。" End Function

lotus2014
質問者

お礼

回答ありがとうございます。 VBAの手順まで示して下さってありがとうございます。 早速テスト環境でマクロを実行してみたところ、一瞬でやりたかった事が終了してしまいました! 本番環境(データ量も多く、フィールド名などが違う)では3時間かかっても動作が終了せず、やはりラクして手に入れたものは身についていないという事もあり、修正するのも大変だなぁ、と痛感しております。 以前に書いて頂いたSQL文が入っていた為、VBAでQ効果とQ使用方法の集計クエリを作って、最後にJoinCSV.csvとして吐き出す処理を指定しているのはなんとなく分かりましたが、その間の命令などが全然理解できていないです^^; まずはこのまま利用させて頂き、このおかげで空いた時間を使ってAccessの勉強をしたいと思います。 本番環境の修正が終わり、正常に動作しましたら後日こちらにご報告いたしますね!

回答No.5

まず、#4 の差し替えですが確認したところ、 256文字以降が切り捨てられてしまいますので Q使用方法は元に戻してください。 TRANSFORM First(Tbl.[使用方法]) AS 使用方法の先頭 SELECT Tbl.薬剤 FROM Tbl GROUP BY Tbl.薬剤 PIVOT '使用方法' & Tbl.[配番]; で、 >「このフォームまたはレポートは、1つのレコードのデータの制限を超えるクエリを基にしています」 また、使用方法の中に半角カンマ , がある可能性も考えてしまいます。 なので、VBA で処理するしかありません。 (Excel2007以降があれば、 Q効果とQ使用方法をExcelに出力して列を切り貼りして整形後にCSV出力・・も考えられますけど。。) VBA での処理でも構わなければ、 CSV で出力した時のフォーマットを教えてください。 各フィールドはダブルクォーテーションで囲むのか。 "A剤","頭痛","1回1錠","発熱","食後…(長文)", 値が無い場合にもダブルクォーテーションが必要か否か。 "A剤","頭痛","1回1錠","発熱","食後…(長文)", を↓ "A剤","頭痛","1回1錠","","", 必要例 "A剤","頭痛","1回1錠",,, 不要例 ヘッダー(タイトル)が必要か否か。(これも囲みの有無) 薬剤/効果1/使用方法1/効果2/使用方法2 /効果3/使用方法3    /・・・ 文字コードは、Shift_JIS で良いのか。 他にも何かあれば、それも含めて確認し、教えてください。

lotus2014
質問者

お礼

回答ありがとうございます。 > Q使用方法は元に戻してください。 私の回答によりSQL文を差し替えて下さったのにすみません… 早速元に戻しました。 > また、使用方法の中に半角カンマ , がある可能性も考えてしまいます。 使用方法には半角カンマの他、ダブルクォーテーションが含まれており、改行は含まれておりません。 > なので、VBA で処理するしかありません。 カンマが含まれる場合はVBAでの処理になってしまうのですね。 SQL文は今後なんとか理解できそうな内容でしたが、VBAとなると今の私のレベルでは理解できるようになるのはかなり先の話です。 それなのにVBAを記述していただくのはありがたい事ですが、気が引けます… …が、折角なので質問に対する回答を記載しました。 > CSV で出力した時のフォーマットを教えてください。 フォーマットというのは以下の質問に答える形で間に合いますか? それともフィールドのデータ型みたいな内容が必要でしたでしょうか? > 各フィールドはダブルクォーテーションで囲むのか。 全てのフィールドをダブルクォーテーションで囲みます。 > 値が無い場合にもダブルクォーテーションが必要か否か。 値が無い場合もダブルクォーテーションが必要となります。 > ヘッダー(タイトル)が必要か否か。(これも囲みの有無) ヘッダーは必要で、ヘッダーのダブルクォーテーションは不要です。 > 文字コードは、Shift_JIS で良いのか。 Shift_JISで大丈夫です。 あと、区切り文字はカンマです。

関連するQ&A

  • ACCESSで縦に並んだテーブルデータを横に並べることは出来ますか?

    お世話になります。現在大量にデータを前に悩んでいます。 テーブルに以下のようなデータがあります。 | 薬剤名 | 効果 | ----------------------- | A剤  | 頭痛 | | A剤  |生理痛 | | A剤  | 発熱 | | B剤  | 歯痛 | | B剤  |生理痛 | | C剤  | 頭痛 | これを、薬剤名ごとにまとめ効果を横へ並べる。 | 薬剤名 |効果1|効果2|効果3|効果4| ------------------------------------------- | A剤  | 頭痛 |生理痛| 発熱 | | | B剤  | 歯痛 |生理痛|   | | | C剤  | 頭痛 |   |   | | ことって出来るのでしょうか? 効果の数はいくつになるか分かりません。現在は最大7つですが、今後それ以上の物が出る可能性もあります。 ACCESSでは無理なことでしょうか? また、ACCESSのバージョンは2002です。なお、ACCESSについては、使用法を含め初心者に毛が生えたくらいの知識しかありません。申し訳ありませんが「サル」にもわかるくらいの優しさでご指導願えれば幸いです。 よろしくお願いします。

  • Access2つのテーブルの差額を出すピボット

    Access2007を使用しています。 以下のような2つのテーブルがあります。 <テーブルA> 区分 品番 金額  数量 A  001 10000  10 A  S12 5000   5 A  002 8000   8 A  001 6000   6 <テーブルB> 区分 品番 金額  数量 B  001 2000  2  B  S12 3000  3 このデータを元に、以下のような結果をピボットで表示したいと思っています。       区分       A  |  B   |合計 品番  数量 金額|数量 金額 |数量 金額 差額(A-B) 001 16 16000| 2 2000 | 18 18000 14000 002 8 8000 |      | 8  8000  8000 S12 5 5000 | 3 3000 | 8  8000  2000 テーブルAとBをユニオンクエリでまとめ、ピボットを作って みたのですが、差額の部分が出せず・・・ どうぞよろしくお願いします。

  • 統計のお話

    Aという薬剤と、Bという薬剤を使用した場合の、それぞれの効果は出せているのですが、これらを併用した場合の効果を統計上で出すことは可能でしょうか? 効果は、血液のデータにより比較しています。 どなたか教えて下さい。 宜しくお願いします。

  • ポンタールが効かない

    最近、耳鼻科でアレルギーとふくびく炎の薬をもらって、もともとの頭痛もちでたまに頭痛がするのでイヴを飲んでることも伝えると、薬の飲み合わせでだめなものもあるからとポンタールを処方されました。 (ふくびく炎の症状で頭痛があることも聞きました。それより元々の頭痛もちであるとは思うのですが) もらってから一度、頭痛のときポンタール1錠飲んでもきかなかったので30分後ぐらいにもう1錠飲みました。 規定で1日2回までとあったので、既定の範囲ないで、そのうち痛みはなくなったので効いてよかったと思ったんですが。 現在、頭痛で先日と同じように1錠飲んでから効かなかったのでもう1錠追加で飲みました。 ですが、全然頭痛の傷み具合がおさまりません。 おでこらへんが痛いんです。 イヴを飲もうかとも考えたんですが、アレルギーの薬との飲み合わせ・・・と言われたので、だめなんだろうけどもう1錠ポンタールを飲みました。 2・3時間で時間差ではありますが3錠飲んでいることになります。 飲んで10分ぐらいはたったでしょうか、まだ痛みは変わらない程度です。 これは私にはポンタールが合わないということでしょうか? それと、3錠短時間に飲んでしまって大丈夫だったでしょうか? こんな時間で、医者にも薬剤師にも問い合わせられず、痛みで顔をゆがめながら書いています。

  • Access処理を自動化するには?

    以下の状況で困っています。お知恵を拝借できれば幸いです。 宜しくお願いいたします。 <状況の作業> 1)システム甲より、特定のフォルダにCSVデータA,Bがエクスポートされる。 2)データAをテーブルAにインポートする。 3)データBをテーブルBにインポートする。 4)テーブルAにある重複をクエリでなくす。(クエリA) 5)クエリAとテーブルBからクエリを使用して最終データを作る。(クエリ最終版) 6)クエリ最終版をエクスポートして、CSVで保存する。(最終版.csv) 7)システム乙に「最終版.csv」をインポートする。 ※メモ   元のCSVがエクスポートされる場所はサーバ上です。   元のCSV名は、「YYYYMMDD_固定部分.csv」で名称が変動します。 <やりたい事> 上記の作業のうち、2)~6)を自動化したい。

  • 【SQL2000】アクセスログからレコメンド機能(ビュー)を作りたい

    SQL文の組み立て方がさっぱりわからないので質問です。 ある商品テーブルの閲覧履歴テーブルから、レコメンドエンジンを 作りたいと思っています。 (amazonなどである「この商品を見た人はこんな商品も見ています」ってヤツです) 以下AテーブルからBのビューを導きたいのですが どのようなSQL文を書けばいいのでしょうか? ■Aテーブル ┌────┬────────┐ │商品番号│見た人     │ ├────┼────────┤ │1    │A        │ ├────┼────────┤ │1    │B        │ ├────┼────────┤ │2    │A        │ ├────┼────────┤ │2    │B        │ ├────┼────────┤ │4    │C        │ ├────┼────────┤ │5    │D        │ ├────┼────────┤ │9    │B        │ ├────┼────────┤ │10   │B        │ ├────┼────────┤ │11   │D        │ ├────┼────────┤ │11   │B        │ ├────┼────────┤ │12   │A        │ ├────┼────────┤ │12   │B        │ ├────┼────────┤ │12   │C        │ └────┴────────┘ ■Bビュー ┌────┬────────┐ │商品番号│他に見た商品番号│ ├────┼────────┤ │1    │2        │ ├────┼────────┤ │1    │12       │ ├────┼────────┤ │2    │1        │ ├────┼────────┤ │2    │12       │ ├────┼────────┤ │11   │5        │ ├────┼────────┤ │11   │1        │ ├────┼────────┤ │11   │2        │ ├────┼────────┤ │11   │10       │ ├────┼────────┤ │11   │12       │ ├────┼────────┤ │12   │1        │ ├────┼────────┤ │12   │2        │ ├────┼────────┤ │12   │4        │ ├────┼────────┤ │12   │9        │ ├────┼────────┤ │12   │10       │ ├────┼────────┤ │12   │11       │ └────┴────────┘ 考え方だけでも構いませんのでご教示いただければ幸いです。

  • Access 長文の文字列結合

    選択クエリAには空のフィールド1があります。 選択クエリCには説明文1というフィールドがあります。 空のフィールド1に説明文1と、ある長文の文字列を収めたい為、以下のようにしました。 選択クエリC.説明文1 & "長文文字列1" AS 空のフィールド1 として、SQLビューへ直接、長文文字列を入力しています。 ※デザインビューにすると「指定した式はクエリのデザイングリッドの1024文字の制限を超えています」と出て開けません。 こういった書き方は力技なのでしょうか? また、この長文の文字列ですが、種類が複数あります。 クエリAのフィールド1には、説明文1と文字列1、フィールド2には、説明文2と文字列2、 クエリBのフィールド1には、説明文1と文字列3、フィールド2には、説明文2と文字列4 など、クエリAやBのような他のクエリを複数作成したい為、 別のスマートな書き方があればご教示いただきたく思っております。 クエリCはデータベースからダウンロードしたものをAccessにインポートして成型した情報で、 クエリA、B等はシリーズ別の説明文の雛形として使用しています。 長文文字列は注意文のようなもので、その中の一文だけが違う文章です。 作業環境は、OS:Windws7、使用ソフト:Access2003となっております。 どうぞ宜しくお願い致します。

  • 1テーブルに対して別々の条件で集計する方法

    以下のような集計を、VIEWを使わずに1回のSQLでできますでしょうか。 【対象TBL】 CD FLG KINGAKU A, 0, 100 A, 0, 200 A, 1, 1000 B, 0, 50 B, 1, 60 【出したい結果】 CD KINGAKU_0 KINGAKU_1 A, 300, 1000 B, 50, 60 普通のSUMで出る以下の結果を、サブクエリなどで横展開しようと試みてるのですが、 うまく出来ません。。 CD FLG KINGAKU A, 0, 300 A, 1, 1000 B, 0, 50 B, 1, 60

  • accessで2フィールドの置換

    以下の方法ではSQLが2回実行されています。1回でできるSQLを教えてください。 a b 1 1 2 1 1 2 2 2 update t set a=3 where a=1; update t set b=3 where b=1; a b 3 3 2 3 3 2 2 2

  • エクセルの表をさらにマトリクス表に展開したい。

    初めて質問させて頂きます。 仕事上でエクセル2003を使用しています。 以下の作業を簡単にできるように、数式またはマクロを組むことを考えています。 表1を表2のように展開する。(例) 表1    A  B  C 1  A1 B1 あいうえお 2  A2 B2 かきくけこ 3  A3 B1 さしすせそ 4  A4 B2 たちつてと 5  A1 B1 なにぬねの 表2    A    B       C   1       B1      B2 2  A1 あいうえお      なにぬねの 3  A2         かきくけこ  4  A3 さしすせそ  5  A4         たちつてと ※行の数は実際はもっと多いです。  また表2のB2に記入してある内容は  複数行になっても構いません。 まずはマクロ(VBA)を使わずにできるかやってみましたが、 VLOOKUPなどでは、なかなかうまくいきません。 よい方法はないでしょうか? VBA使用でもかまいません。 ヒントだけでもぜひよろしくお願いします。

専門家に質問してみよう