[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『月の文字が含まれるシートで処理をさせたい』(佐藤)
月別に分かれたシートを集計するための共通項を設定したいのですが、動きません。
(シートの選択のみ動きます)
Sh.Selectの前に仮で「Range("A1")="あああ"」と入れると1月〜11月までは処理されましたが12月は変化なしだし、発着の整理の式を入れても処理はしてもらえませんでした。
Sub 発着地設定()
Dim sh As Object Dim j As Long
'------シート選択
Const FIND_STR = "月"
For Each sh In Sheets If sh.Name Like "*" & FIND_STR Then
sh.Select
'------発着の整理
For j = 2 To lastrow Cells(j, "A") = Range("E" & j).Value & "→" & Range("G" & j).Value
Next j
End If Next sh
End Sub
< 使用 Excel:Excel2016、使用 OS:Windows10 >
前回の踏まえていませんが、これでどうでしょう? Sub 発着地設定() Dim sh As Worksheet Dim j As Long '------シート選択 For Each sh In Sheets If sh.Name Like "*月" Then With sh For j = 2 To .Cells(Rows.Count, "A").End(xlUp).Row .Cells(j, "A").Value = .Cells(j, "E").Value & "→" & .Cells(j, "G").Value Next j End With End If Next sh End Sub (稲葉) 2019/03/11(月) 16:02
どちら様でしょう? (稲葉) 2019/03/11(月) 16:12
そらSelectしないですから、見た目はしてないですよ。 A列が空欄でしたら >For j = 2 To .Cells(Rows.Count, "A").End(xlUp).Row この部分の"A"を"E"に変えてみてください。 (稲葉) 2019/03/11(月) 16:48
>シートが選択されるだけで処理をしないため これについてコメントしますと、元のコードのlastrowに何も入っていないので0扱い?だから
> For j = 2 To lastrow 2 to 0だとそのまま処理抜けます。
(稲葉) 2019/03/11(月) 16:53
集計方法を下のマクロを参考に組もうとしているのですが、自分でも応用してやってみますがやり方がおかしかったらご指摘ください。
'====================集計
'Dictionaryオブジェクトをセット
Set DicT = CreateObject("Scripting.Dictionary")
'範囲の最終セル取得
LR = ws1.Cells(Rows.Count, 2).End(xlUp).Row
'配列化 Dim i As Long '範囲内でKey取得を繰り返す For i = 2 To LR 'Keyが既に配列にある場合は金額を加算する If DicT.Exists(ws1.Cells(i, 2).Value) Then DicT.Item(ws1.Cells(i, 2).Value) = _ DicT.Item(ws1.Cells(i, 2).Value) + ws1.Cells(i, 5).Value Else 'Keyがなければ配列に追加する DicT.Add ws1.Cells(i, 2).Value, ws1.Cells(i, 5).Value End If Next i
'取得したKeyをセルに返す Ke = DicT.keys For i = 0 To DicT.Count - 1 ws1.Cells(2 + i, 8) = Ke(i) Next i
'合計したItemをセルに返す It = DicT.Items For i = 0 To DicT.Count - 1 ws1.Cells(2 + i, 11) = It(i)
'---カンマに変更--- ws1.Cells(2 + i, 11).Select Selection.Style = "Comma [0]" Next i (佐藤) 2019/03/11(月) 17:21
せめてSubからEnd Subまで提示いただけないですか? あとインデントもつけていただけると読みやすいです。 (稲葉) 2019/03/11(月) 17:27
一応提示された範囲で・・・ あくまで私個人の見解です。 気づいた点 1)変数宣言は必ずする 2)一度しか使わない変数(例えばLRとか)は、分かりにくくならない範囲で使わない 3)DictionaryはExists判定しなくても、加算とかには使える。(例外あり。DictionaryのItemに配列やオブジェクトを入れるなど。) 4)Dictionaryはループしなくても、書き出せる(但し、Transposeを使うので、上限あり大体60,000くらい) 5)Cellsの行番号は、ループで使用しない限り文字列で指定する。(可読性向上) 6)Selectはまず使わない。(最後に表示させたいシートを出すくらい) Sub a() Dim dicT As Object Dim ws1 As Worksheet Dim i As Long Set ws1 = Sheets("Sheet1") Set dicT = CreateObject("Scripting.Dictionary") 'Dictionaryオブジェクトをセット For i = 2 To ws1.Cells(Rows.Count, "B").End(xlUp).Row dicT(ws1.Cells(i, "B").Value) = dicT(ws1.Cells(i, "B").Value) + ws1.Cells(i, "E").Value 'B列のキーにE列の値を加算 Next i ws1.Cells(2, "H").Resize(dicT.Count).Value = Application.Transpose(dicT.keys) 'H列にキー(B列の値)を返す With ws1.Cells(2, "K").Resize(dicT.Count) .Value = Application.Transpose(dicT.items) 'K列にアイテム(金額)を返す .Style = "Comma [0]" End With Set dicT = Nothing End Sub (稲葉) 2019/03/11(月) 17:59
Set ws1 = Sheets("Sheet1")
の部分をどうやって選択するのかを悩んでいました。
A ・・・ T
あああ→いいい 1000
いいい→あああ 2000
ううう→いいい 10000
あああ→いいい 2000
このようなシートが1月〜12月まで
集計シート
A B
あああ→いいい 3000
いいい→あああ 5000
と集計したかったです。なんか複雑にしている感じはしますが・・・
(佐藤) 2019/03/11(月) 18:10
埒空かないので、テストデータこっちで準備しました。 1)新しいブックを作ってください。 2)標準モジュールにmkTestDataをコピーして、実行してください。 3)標準モジュールに集計をコピーして、実行してください。 こういうことでいいんですか? 最初の質問とかけ離れていますが、それも付け足すんですか? Sub mkTestData() Dim i As Long For i = 1 To 12 With Sheets.Add(after:=Sheets(Sheets.Count)) .Name = i & "月" With .Range("A2:A50") .Formula = "=CHOOSE(RANDBETWEEN(1,3),""あああ"",""いいい"",""ううう"")" .Value = .Value End With With .Range("T2:T50") .Formula = "=RANDBETWEEN(1,9)*1000" .Value = .Value End With End With Next i With Sheets.Add(after:=Sheets(Sheets.Count)) .Name = "集計" End With End Sub Sub 集計() Dim i As Long Dim ws As Worksheet With CreateObject("Scripting.Dictionary") For Each ws In Sheets If ws.Name Like "*月" Then For i = 2 To ws.Cells(Rows.Count, "A").End(xlUp).Row .Item(ws.Cells(i, "A").Value) = _ .Item(ws.Cells(i, "A").Value) + ws.Cells(i, "T").Value 'A列のキーにT列の値を加算 Next i End If Next ws Sheets("集計").Range("A1").Resize(.Count).Value = Application.Transpose(.keys) Sheets("集計").Range("B1").Resize(.Count).Value = Application.Transpose(.items) Sheets("集計").Range("B:B").NumberFormat = "#,##0" End With End Sub
(稲葉) 2019/03/11(月) 18:36
A B C D E
月 発→着 発地 着地 金額
1月度 あああ→いいい あああ いいい 10000
・
・
・
12月度 いいい→かかか いいい かかか 7000
というふうにA列にシート名+度、B列にデータシートA列、E列にその集計としたいです。
(CとE列は「→」の前と後ろで抽出する予定でした)
(佐藤) 2019/03/12(火) 08:47
まず (稲葉) 2019/03/11(月) 18:36 これで作った表とコードで動くかどうか教えてもらえませんか? 話はそのあとです。 >(佐藤) 2019/03/11(月) 18:10 の提示に沿って作ったデータなので、これが正しくないとすると最初からやり直しになります。
また 表を提示する場合は、Wikiの整形ルール(このコメント欄の下方)に沿って >行頭を半角スペースで始めると書き込みの改行位置が反映されます。 提示してください。
あるいは下記コードを使って、データシートと集計シートをこちらに張り付けてください。 ' BrkStr:列間の文字列 初期値は「|」 '===================================================== ' 投稿用シートレイアウトをクリップボードに取得 ' 作成者(momo) ' ' BrkStr:列間の文字列 初期値は「|」 ' DataObjectID:DataObjectのLate Binding用(変更不可) ' https://www.excel.studio-kazu.jp/kw/20110209184943.html '===================================================== Const BrkStr As String = "|" Const DataObjectID As String = "1C3B4210-F441-11CE-B9EA-00AA006B1A69" Dim myRng As Range Dim rngFormula As Range Dim rngBuf As Range Dim tbl() As Variant Dim AryTxt() As String Dim StrBuf As String Dim i As Long Dim j As Long Dim cnt As Long Dim AryWidth() As Long Dim LenBuf As Long cnt = 1 On Error Resume Next Set myRng = Application.InputBox("取得したい範囲を選択してください。", Type:=8, Default:=Selection.Address) On Error GoTo 0 If myRng Is Nothing Then '何も選択されなかったら、何もしない。 Else 'If MsgBox("数式として表示したい範囲はありますか?", vbYesNo) = vbYes Then Do On Error Resume Next Set rngBuf = Application.InputBox("数式として表示したい範囲を選択してください。" & cnt & "個目", Type:=8) On Error GoTo 0 If Not rngBuf Is Nothing Then If rngFormula Is Nothing Then Set rngFormula = rngBuf Else Set rngFormula = Application.Union(rngFormula, rngBuf) End If cnt = cnt + 1 Else Exit Do End If Set rngBuf = Nothing Loop 'While MsgBox("さらに数式として表示したい範囲がありますか?", vbYesNo) = vbYes 'End If ReDim tbl(1 To myRng.Rows.Count, 1 To myRng.Columns.Count) ReDim AryWidth(1 To UBound(tbl, 2)) For i = 1 To myRng.Rows.Count For j = 1 To myRng.Columns.Count tbl(i, j) = myRng.Cells(i, j).Text If Not rngFormula Is Nothing Then If Not Application.Intersect(myRng.Cells(i, j), rngFormula) Is Nothing Then tbl(i, j) = myRng.Cells(i, j).Formula End If End If LenBuf = Application.Evaluate("LENB(""" & Replace(tbl(i, j), """", vbTab) & """)") If AryWidth(j) < LenBuf Then AryWidth(j) = LenBuf End If Next j Next i ReDim AryTxt(UBound(tbl, 1)) AryTxt(0) = String(Len(myRng.Rows(myRng.Rows.Count).Row) + 3, " ") For i = 1 To UBound(tbl, 2) StrBuf = "[" & Split(myRng.Columns(i).EntireColumn.Address(False, False), ":")(0) & "]" If AryWidth(i) > Len(StrBuf) Then AryTxt(0) = AryTxt(0) & BrkStr & StrBuf & String(AryWidth(i) - Len(StrBuf), " ") Else AryTxt(0) = AryTxt(0) & BrkStr & StrBuf AryWidth(i) = Len(StrBuf) End If Next i For i = 1 To UBound(tbl, 1) AryTxt(i) = " [" & myRng.Rows(i).Row & "]" & _ String(Len(myRng.Rows(myRng.Rows.Count).Row) - Len(myRng.Rows(i).Row), " ") For j = 1 To UBound(tbl, 2) LenBuf = Application.Evaluate("LENB(""" & Replace(tbl(i, j), """", vbTab) & """)") If IsNumeric(tbl(i, j)) Then AryTxt(i) = AryTxt(i) & BrkStr & String(AryWidth(j) - LenBuf, " ") & tbl(i, j) Else AryTxt(i) = AryTxt(i) & BrkStr & tbl(i, j) & String(AryWidth(j) - LenBuf, " ") End If Next j Next i With GetObject("new:" & DataObjectID) .SetText Join(AryTxt, vbCrLf) .PutInClipboard End With MsgBox "クリップボードにコピーしました。" End If End Sub
(稲葉) 2019/03/12(火) 08:57
(稲葉) 2019/03/11(月) 18:36
こちらのコードで集計出来ました。
ううう 963000
いいい 979000
あああ 1047000
で集計されました。
お手数をおかけしてしまい申し訳ございません。
(佐藤) 2019/03/12(火) 10:01
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.