アプリ版:「スタンプのみでお礼する」機能のリリースについて

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

A 回答 (4件)

> 既存のものとのからみで、別々の場所にしなければならないのです。



提案します。

現在の CSV の位置を動かせないなら、別途 Tmp フォルダに CSV をコピー
して、そこをワークフォルダとしてみれば?

ファイルのコピー方法は、

 ・FileCopy を使った方法(VBA 標準コマンド)
  http://officetanaka.net/excel/vba/statement/File …
 ・CopyFile を使った方法(FileSystemObject)
  http://officetanaka.net/excel/vba/filesystemobje …

などがあります。作業が終わったら、

 ・Kill ステートメント(VBA 標準コマンド)
  http://officetanaka.net/excel/vba/statement/Kill …
 ・DeleteFile メソッド(FileSystemObject)
  http://officetanaka.net/excel/vba/filesystemobje …

などで削除することもできますよ。
    • good
    • 0
この回答へのお礼

提案していただいたとおり、TEMPフォルダーにCSVをコピーしたところ私の知識の範囲で解決できました。
ありがとうございました。

お礼日時:2008/10/02 11:12

詳しい方のようですね。

ご参考までに。

> SQLを使った集計の方が早いかなと思い
うーん。。ソース次第でしょう。
> また、テーブルのレコード数が65535を超えるものもあります
それなら確かに SQL を使った方が楽ですね。

> D:\DATA\ORDER\SOURCE.CSVに売上のデータがあり、
> D:\DATA\STOCK\SOURCE.CSVに在庫のデータがあります。

1. 2つの CSV は同一フォルダに置いて下さい
  複数のフォルダに分散させると面倒ですよ。多分。以下説明用に
    
    D:\DATA フォルダ
    売上データを o.csv、
    在庫データを s.csv
  
  とします。

2. ADO 接続について
  ADO 定数をイチイチ再定義するのは面倒なのでアーリーバインドで。
  なるべく広い環境の PC で動作するように
  
    Microsoft ActiveX Data Objects 2.6 Library
  
  あたりの多少古いライブラリを参照しておくと良いと思います。
  で、具体的なコード例ですが....

  ' // 変数の宣言等は省略
' // CSV フォルダパス
  sCsvDir = "D:\DATA"
  
  ' // CSV 接続文字列(HDR= ラベル有無)
  sConnectionStr = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
           "Data Source=" & sCsvDir & ";" & _
           "Extended Properties=""Text;HDR=YES;FMT=Delimited"""

  ' // SQL 生成
  sql = "次項目で説明"
  
  ' // CSV に接続してレコードセットを取得
  Set cn = CreateObject("ADODB.Connection")
  cn.Open sConnectionStr
  Set rs = CreateObject("ADODB.Recordset")
  rs.Open sql, cn, adOpenForwardOnly, adLockReadOnly

  ' // ワークシートに展開
  ' // もちろん Rows.Count(Excel2003 までなら 65536)を越える
  ' // 場合は別途処理が必要
  Range("A2").CopyFromRecordset rs

  ' // 後処理(略)


3. SQL の書き方(一例)

  テーブルの指定に該当する部分は [s#csv] のように書きます。

  SELECT
   [s#csv].[在庫No],
   DATEDIFF('d',[s#csv].[仕入日],[o#csv].[売上日]) AS [滞留日数],
   [o#csv].[売上額]-[s#csv].[仕入額]) AS [粗利益],
   [o#csv].[注文No]
  FROM [s#csv] LEFT JOIN [o#csv] ON [s#csv].[在庫No] = [o#csv].[在庫No];

  当然、売れないモノもあるでしょうから、[売上日] が Null の場合
  なんかも考慮して SQL を書いて下さい。

では。

この回答への補足

返信がおそくなりました。自分で書き込んだつもりで書き込んでいなかった。どうりで返答がこないはずだ(笑)
>詳しい方のようですね
詳しくないです。
回答3で教えていただいた内容ならば、ネット上に参考になるサイトが多々ありましたので、なんとかかけます。
しかし、
>2つの CSV は同一フォルダに置いて下さい
>複数のフォルダに分散させると面倒ですよ。
既存のものとのからみで、別々の場所にしなければならないのです。
その「面倒」なことのフローチャートというか箇条書きにでも処理を教えていただければ・・・

補足日時:2008/09/29 12:25
    • good
    • 1

こんにちは。



> 2つのCSVを結合した結果をADOでレコードセットに格納したい場合
> どのようなソースになるのでしょうか?

2 つの CSV を 1 ブック上にシートを分けて展開すれば、あとは関数
VLOOKUP 等と作業列の使用で何とかなることだと思います。

ゆえに疑問に思うのですが、レコードセットを作成した後に何がしたい
のでしょうか? 目的が書かれてません。

単にレコードセット作成の実験的コードを知りたいのか、実用に耐える
ものが知りたいのか、目的によって回答が変ってくると思います。

この回答への補足

返信が遅くなりました。
さて、なぜこのようなコードを知りたいのかといいますと、今までMSSQLでDTSを使用し取り込み、ODBCでエクセルにストアドプロシージャの値を返すような形でいたのですが、今度DBサーバーを撤去しするので、MSSQLを使用せずにCSVからMSSQLを介さず直接エクセルにということになりました。そこで、どうしたらよいか思案中というところでして。
VLOOKUP等を使用する場合も考えましたが、SQLを使った集計の方が早いかなと思いこういった質問をしました。また、テーブルのレコード数が65535を超えるものもありますので

補足日時:2008/09/05 09:13
    • good
    • 0

  Dim isOK      As Boolean


  Dim I       AS Integer
  Dim N       AS Integer
  Dim strUriages()  As String
  Dim strZaikos()  As String
  Dim strStockNumber As String
  Dim strSQL     AS String

  strUriages() = FileReadArray("D:\DATA\ORDER\SOURCE.CSV")
  N = UBound(strUriages())
  For I = 0 To N
    strStockNumber = CutStr(strUriages(I), ",", 4)
    strZaikos() = FileFindArray("D:\DATA\STOCK\SOURCE.CSV", "*" & strStockNumber & "*")
    strSQL = "INSERT INTO ・・・・・" & _
     "・・・・・・"
    isOK = CnnExecute(strSQL)
    If Not isOK Then
   MsgBox "深刻なエラーが発生しましたので処理を中断します"
       Exit For
    End If
  Next I

FileReadArray()・・・CSV データを AAA,BBB,CCC を1レコードとする配列に呼び込む。
CutStr()・・・・・・・・・・CSV データからN番目を取り出す。
FileFindArray()・・・CSV データの第二引数にマッチする行を配列で返す。
CnnExecute・・・・・・・・SQL文を実行する。

こういう関数を用意すれば、こういう処理の流れで可能。
で、で、関数も含めての全容となるとかなりヘビーな回答になると思います。

***********************************
 ただし、その必要はないのでは?
***********************************

で、その必要はないと思いますよ。

10 INPUT A, B
20 C = A * B
30 PRINT C

コンピュータ処理は、単純化すればこの3行。

10 INPUT A * B TO C
20 PRINT C

で、質問者の構想はこのようです。
つまり、データの入力と処理とが渾然一体に。
これは、不必要で無駄な処理。

10 INPUT A, B
20 PRINT A * B

と、入力データの参照段階で色々と処理するのが基本だと思います。
    • good
    • 0
この回答へのお礼

解答ありがとうございます
私はてっきり、
Con.Open "Driver={Microsoft Text Driver (*.txt; *.csv)};DBQ=" & Path & ";ReadOnly=0"
strSQL = "select * from aaa.csv"
rs.Open strSQL, Con, adOpenForwardOnly
の流れで・・・例えばCon2とrs2を用意して、rsとrs2を選択できるかな~位の感覚で質問しました。なぜこのような質問かというのは別の方に頂いた解答に補足事項に記載してあります

お礼日時:2008/09/05 09:33

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!