プロが教える店舗&オフィスのセキュリティ対策術

vb.netでCSVファイルを変換して新しいCSVファイルを作りたいのですが、どのようにすれば良いかヒントを教えていただけないでしょうか?

A組,10代,10
A組,20代,20
A組,30代,30
B組,10代,40
B組,20代,50
B組,30代,60
C組,10代,70
C組,30代,80

この様なCSVファイルを変換して

,A組,B組,C組
10代,10,40,70
20代,20,50,
30代,30,60,80

という表のようなCSVファイルを作りたいのです。
データベースなどに入れずに、ファイルtoファイルでの変換がしたいです。
最初のファイルの1列目と2列目の項目をそれぞれ配列に入れて重複をなくす位までは思いつくのですが、そこから先がどの様にすれば良いかよく分かりません。
ヒントだけでも良いのでよろしくお願いいたします。

A 回答 (3件)

入力CSVファイルに対し、ODBCテキストドライバーを割り当て。


テーブルとして操作できるので、クロス集計する。
クロス集計で得られた結果をCSV出力。
    • good
    • 0
この回答へのお礼

教えていただいたやり方はやってみようと思っています。
調べてみたのですが、datasetやdatatableの使い方をまだ理解できていないので、もうちょっと勉強していきます。
助かりました。ありがとうございます。

お礼日時:2010/08/09 20:03

(1)エクセルVBAを知っておれば、エクセルの機能とVBAでできます。


ソート機能を途中で使うのが、一番ロジックが簡単になると思う。
(2)VB.NETからエクセルVBAに入り、エクセルVBAコードで処理をする方法もあります。
(3)アクセスがあればアクセスに持ち込んで(エクセル経由になるかも)、クロス集計するとか
SQLで出来る。
(4)既に出ている、多様なファイルを扱えるODBC利用とか
(5)VB.NETでは、CSVは各項目のレコードの初めからの位置が不定で、テキストファイルのソートはできないと思う。すると配列なりに一旦蓄えて、自作ソート(世代で)し、後は同世代複数レコードを1レコード化(フィールド化)すれば良い。
昔はメモリが少なく、レコードの溜め込み(配列)は避けたように思う。いまの人はその苦しみは少ない。
ーー
(6)配列をソートせずに、全配列をなめて、その世代に該当する配列を探し出しても良い。
10代、20代、・・70代等7-8回繰り返せばよい。レコード数が膨大(何百万)でなければ、実行は直ぐ終わるだろう。
(7)配列のソート
http://www.atmarkit.co.jp/fdotnet/dotnettips/215 …
のようにVB.NETになってやれることが増えた。自作しないでも良いかも。
「vb.net 配列 ソート」でGoogle照会のこと。
配列のソート的なことも出来る。
ーー
>A組,B組,C組
10代,10,40,70
A組10代は複数人出現するのでしょうね。例はその点を判るように挙げるべき。
当然該当者は足しこむのだろうね。
    • good
    • 0
この回答へのお礼

色々なやり方を教えていただくと、本当に助かります。
出来る限り他のやり方も試したいと思います。

例のA組の10代は足しこんだ後の数値でした。しかし例が分かりにくかったと思います。今後気をつけるようにします。

大変為になりました。ありがとうございます。

お礼日時:2010/08/09 19:57

SortedDictionaryを使うのは如何でしょう?


Dim Q As New SortedDictionary(Of String, _
    SortedDictionary(Of String, Integer))
Qのキーは10代、20代、等の項目になります。
QのデータはSortedDictionaryで、キーはA組、B組等、
データは数値(3列目)です。
ランダムに書き込んでも、ソートされて記録されますので、
ファイルの入力処理後にFor Each文でデータを出力すれば
目的のように出力できます。

Dim A As New StreamReader("C:~.csv", _
    Encoding.GetEncoding("shift_jis"))
Dim B As New SortedDictionary(Of String, Integer)
Dim C As New SortedDictionary(Of String, _
    SortedDictionary(Of String, Integer))
Dim D As String
Dim E
Do Until A.EndOfStream
    D = A.ReadLine
    E = D.Split(",")
    If Not B.Keys.Contains(E(0)) Then B.Add(E(0), 0)
    Dim F As SortedDictionary(Of String, Integer)
    If C.Keys.Contains(E(1)) Then
        F = C(E(1))
        If F.Keys.Contains(E(0)) Then
            F(E(0)) = F(E(0)) + E(2)
        Else
            F.Add(E(0), E(2))
        End If
    Else
        F = New SortedDictionary(Of String, Integer)
        F.Add(E(0), E(2))
        C.Add(E(1), F)
    End If
Loop
A.Close()
Dim G = New StreamWriter("C:\~.csv", False, _
    Encoding.GetEncoding("shift_jis"))
For Each H As String In B.Keys
    G.Write("," & H)
Next
G.WriteLine("")
For Each H As String In C.Keys
    G.Write(H)
    Dim F As SortedDictionary(Of String, Integer) = C(H)
    For Each D In B.Keys
        If F.Keys.Contains(D) Then
            G.Write("," & F(D).ToString())
        Else
            G.Write(",0") '省略時はコメントアウト
        End If
    Next
    G.WriteLine("")
Next
G.Close()
    • good
    • 0
この回答へのお礼

思い通りに出力をすることが出来ました。
キーを二つ持つやり方を色々試していたので、まさにやりたいことを教えていただきました。
大量のデータを扱う場合でも遅くならないか検証をしていこうと思います。

大変助かりました。ありがとうございます。

お礼日時:2010/08/09 19:47

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