回答受付中の質問
はじめまして最近Excelvbaを勉強し始めた初心者です。
早速質問なんですが例えば↓
東京 150 200
大阪 230 100
大阪 100 50
大阪 100 300
福岡 250 300
沖縄 500 100
こんな表があるとします。
大阪のように同じ名前が連続した時に↓
東京 150 200
大阪 230 100
大阪 100 50
大阪 100 300
小計 430 450
福岡 250 300
沖縄 500 100
このように大阪の下に小計欄を作成して
合計を求めたいのですが、
連続する可能性のある言葉は把握しています(複数あり)
Excelvbaで出来ますか?
僕なりに考えてみたんですが無理でした・・・
どなたか詳しい方、知恵を貸して下さい。
お願いいたします。
投稿日時 - 2005-10-26 21:43:23
0人が「このQ&Aが役に立った」と投票しています
回答(3件中 1~3件目)
ファイルはCSV形式でしょうか?
Likeを使う場合は比較する対象が固定の場合が多いので、この場合はLeft関数でいいと思います。
一応こんな感じでしょう。
注意:エラーハンドリングはしてません、必要に応じて追加下さい。
全てのテストケースを網羅した訳ではありません、必要に応じて修正下さい。
また、ソースコードの最適化もあまりしてません。
Sub Create_List()
Dim R2 As Range
Range("A1").Activate
Call Load_File(ActiveWorkbook.Path & "\File1.csv", 1)
Range("A1").Activate
Call SubToTal
Set R2 = ActiveCell
Call Load_File(ActiveWorkbook.Path & "\File2.csv", 2)
R2.Activate
Call SubToTal
Call Data_Sort1
Call List_Create
Call Data_Sort2
End Sub
Sub Load_File(FNM As String, FNO As Integer)
Dim FID As Integer
Dim FFLD(2) As Variant
i = 1
FID = FreeFile(0)
Open FNM For Input As FID
Do While Not EOF(FID)
Input #FID, FFLD(0), FFLD(1), FFLD(2)
ActiveCell.Value = FFLD(0)
ActiveCell.Offset(0, 1).Value = FFLD(1)
ActiveCell.Offset(0, 2).Value = FFLD(2)
ActiveCell.Offset(0, 3).Value = FNO
ActiveCell.Offset(1, 0).Activate
Loop
Close #FID
End Sub
Sub SubToTal()
Dim i As Integer
Dim LSw As Boolean
Dim TLT(1) As Long
Dim STTLT As String
i = 1: ActiveCell.Offset(0, 4).Value = 1
Do While ActiveCell.Text <> ""
LSw = True
Do While LSw
If ActiveCell.Offset(0, 4).Value <> 1 Then
ActiveCell.Offset(0, 3).Value = ActiveCell.Offset(-1, 3).Value
ActiveCell.Offset(0, 4).Value = ActiveCell.Offset(-1, 4).Value + 1
End If
If Left(ActiveCell.Text, 2) <> Left(ActiveCell.Offset(1, 0).Text, 2) Then
If i > 1 Then
ActiveCell.Offset(1, 0).Activate
Selection.EntireRow.Insert
ActiveCell.Value = ActiveCell.Offset(-1 * i, 0).Text & "計"
ActiveCell.Offset(0, 1).Value = TLT(0) + ActiveCell.Offset(-1, 1).Value
ActiveCell.Offset(0, 2).Value = TLT(1) + ActiveCell.Offset(-1, 2).Value
ActiveCell.Offset(0, 3).Value = ActiveCell.Offset(-1, 3).Value
ActiveCell.Offset(0, 4).Value = ActiveCell.Offset(-1, 4).Value + 1
End If
i = 1
LSw = False
TLT(0) = 0
TLT(1) = 0
Else
i = i + 1
TLT(0) = TLT(0) + ActiveCell.Offset(0, 1).Value
TLT(1) = TLT(1) + ActiveCell.Offset(0, 2).Value
End If
ActiveCell.Offset(1, 0).Activate
Loop
Loop
End Sub
Sub Data_Sort1()
Range("A1").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Sort Key1:=Range("A1"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod _
:=xlPinYin, DataOption1:=xlSortNormal
Range("A1").Select
End Sub
Sub List_Create()
Dim i As Integer
Do While ActiveCell.Text <> ""
If ActiveCell.Offset(0, 3).Text = 2 Then
If ActiveCell.Row <> 1 Then
If ActiveCell.Text = ActiveCell.Offset(-1, 0).Text Then
ActiveCell.Offset(-1, 5).Value = ActiveCell.Text
ActiveCell.Offset(-1, 6).Value = ActiveCell.Offset(0, 1).Text
ActiveCell.Offset(-1, 7).Value = ActiveCell.Offset(0, 2).Text
Selection.EntireRow.Delete
ActiveCell.Offset(-1, 0).Activate
Else
ActiveCell.Offset(0, 5).Value = ActiveCell.Text
ActiveCell.Offset(0, 6).Value = ActiveCell.Offset(0, 1).Text
ActiveCell.Offset(0, 7).Value = ActiveCell.Offset(0, 2).Text
ActiveCell.Value = ""
ActiveCell.Offset(0, 1).Value = ""
ActiveCell.Offset(0, 2).Value = ""
End If
Else
ActiveCell.Offset(0, 5).Value = ActiveCell.Text
ActiveCell.Offset(0, 6).Value = ActiveCell.Offset(0, 1).Text
ActiveCell.Offset(0, 7).Value = ActiveCell.Offset(0, 2).Text
Range(ActiveCell.Address & ":" & ActiveCell.Offset(0, 4).Address).Delete Shift:=xlUp
End If
End If
ActiveCell.Offset(1, 0).Activate
Loop
End Sub
Sub Data_Sort2()
Range("A1", ActiveCell.Offset(-1, 7)).Select
Selection.Sort Key1:=Range("E1"), Order1:=xlAscending, Key2:=Range("D1") _
, Order2:=xlAscending, Header:=xlGuess, OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom, SortMethod:=xlPinYin, DataOption1:= _
xlSortNormal, DataOption2:=xlSortNormal
Columns("D:E").Delete Shift:=xlToLeft
Range("A1").Select
End Sub
勉強始めたばかりであればもう少し簡単なものから手を付けた方が良いと思いますよ。
本来は少し書いては試しを繰り返して完成させないと勉強にならないので。
まぁ頑張って下さい。
投稿日時 - 2005-10-28 12:46:17
お礼
ありがとうございます!
leftを使ってみたらできました。
そうですね~ちょっと難しいとこに手をつけたかもしれませんね。
勉強になりました。
ほんとうにありがとうございます、、
投稿日時 - 2005-10-28 23:41:59
サンプルが欲しいのか分からないのですが....
以下は元のデータシートを直接操作する2例です。
◆重複するデータ数が少ない場合は以下(合計で後戻りするので次の例より遅い)
Sub SubToTal()
Dim i, j As Integer
Range("A1").Activate
i = 1
Do While ActiveCell.Text <> ""
If ActiveCell.Text <> ActiveCell.Offset(1, 0).Text Then
If i > 1 Then
ActiveCell.Offset(1, 0).Activate
Selection.EntireRow.Insert
ActiveCell.Value = ActiveCell.Offset(-1, 0).Text & "計"
For j = -1 To i * -1 Step -1
ActiveCell.Offset(0, 1).Value = ActiveCell.Offset(0, 1).Value + ActiveCell.Offset(j, 1).Value
ActiveCell.Offset(0, 2).Value = ActiveCell.Offset(0, 2).Value + ActiveCell.Offset(j, 2).Value
Next
i = 1
End If
Else
i = i + 1
End If
ActiveCell.Offset(1, 0).Activate
Loop
End Sub
◆重複するデータ数が多い場合は以下(合計で後戻りしないので前のより速い)
Sub SubToTal()
Dim i As Integer
Dim LSw As Boolean
Dim TLT(1) As Long
Range("A1").Activate
i = 1
Do While ActiveCell.Text <> ""
LSw = True
Do While LSw
If ActiveCell.Text <> ActiveCell.Offset(1, 0).Text Then
If i > 1 Then
ActiveCell.Offset(1, 0).Activate
Selection.EntireRow.Insert
ActiveCell.Value = ActiveCell.Offset(-1, 0).Text & "計"
ActiveCell.Offset(0, 1).Value = TLT(0) + ActiveCell.Offset(-1, 1).Value
ActiveCell.Offset(0, 2).Value = TLT(1) + ActiveCell.Offset(-1, 2).Value
End If
i = 1
LSw = False
TLT(0) = 0
TLT(1) = 0
Else
i = i + 1
TLT(0) = TLT(0) + ActiveCell.Offset(0, 1).Value
TLT(1) = TLT(1) + ActiveCell.Offset(0, 2).Value
End If
ActiveCell.Offset(1, 0).Activate
Loop
Loop
End Sub
両コードともに処理完了するまで「Application.ScreenUpdating」を使用して画面更新を行わないことでもう少し高速化出来ますが初心者にはお勧めしません。
VBAの勉強中とのことなのでコードの説明は省きました。
頑張って調べて下さい。
投稿日時 - 2005-10-27 09:54:35
補足
回答ありがとうございます。
処理結果をみて驚いてます!
私も勉強してXenさんみたいになれたらとおもいます。
あと一つ出きれば教えていただきたいのですが、
例えば
FILE1 FILE2
東京 東京
大坂 大坂
大坂府 大坂府知事
大坂城 福岡
大坂府知事 沖縄
福岡
沖縄
こんな2つのFileがあるとします。
これを照合して↓
東京 東京
大坂 大坂
大坂府
大坂城
大坂府知事 大坂府知事
計 計
福岡 福岡
沖縄 沖縄
と完全に合ってない文字を(大坂の部分は把握してます)
見比べて大坂の部分が共通ならカウントして計をつくる。
またもう一つのFileとも見比べて大坂の部分で入ってない欄があったらスペースを入れて同じ列に計を入れたいんです。
If ActiveCell.Text <> ActiveCell.Offset(1, 0).Text Thenの部分を変えるのは何となく分かるんですが・・・
Likeをつかうんですか?
すみませんが知恵を貸して下さい。
投稿日時 - 2005-10-27 11:30:11
OKWaveのオススメ
おすすめリンク