[[20210502075123]] 『行数を限定して表示させるには』(nobu) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『行数を限定して表示させるには』(nobu)

以前 ListViewについて質問した者ですが読み込む(吸い上げる)行数が
月日とともに多くなり全ての行数を読みこむ必要が無いのですが制限を
掛ける仕方がわかりません、ご教授お願いします。

以下のマクロでは、振込一覧シートのB列全てを表示させるようなコードに
仕様に作られております、以下の部分だと思うのですが
3 To Sheets("振込一覧").Range("B" & Rows.Count).End(xlUp).Row

現在、約2500行ほどの帳票として(過去からの積み重ねで)年月とともに
増えてしまいました一番下の行のマクロで降順にして表示させておりますが
大体利用する行数が300行(降順にした状態で最近入力したデータ)あれば
問題ないのですが B列は日付が入力してある行です。そこで一定行数で
切って利用できないかと考えております。

このあたりのvbaの書き方改良の仕方を教えていただだけないでしょうか
よろしくお願いします。

Private Sub UserForm_Activate()

    Dim DBpath As String
    Dim i As Long

      With ListView1
        .View = lvwReport
        .LabelEdit = lvwManual
        .HideSelection = False
        .AllowColumnReorder = True
        .FullRowSelect = True
        .Gridlines = True

        .ColumnHeaders.Add , "_nengaltupi", "年月日", 80, lvwColumnLeft
        .ColumnHeaders.Add , "_hurikomisaki", "振込先", 180, lvwColumnLeft
        .ColumnHeaders.Add , "_koumei", "銀行名", 100, lvwColumnLeft
        .ColumnHeaders.Add , "_sitenmei", "支店名", 80, lvwColumnLeft
        .ColumnHeaders.Add , "_siharaikingaku", "振込金額", 105, lvwColumnRight
        .ColumnHeaders.Add , "_anzen", "会費", 80, lvwColumnRight
        .ColumnHeaders.Add , "_sousai", "相殺", 80, lvwColumnRight
        .ColumnHeaders.Add , "_utiwake", "内訳", 114, lvwColumnLeft
        .ColumnHeaders.Add , "_tesuuryou", "手数料", 70, lvwColumnRight
      End With

    If Not m_ShownFlag Then
        With ListView1
            For i = 3 To Sheets("振込一覧").Range("B" & Rows.Count).End(xlUp).Row
            With .ListItems.Add(Text:=Sheets("振込一覧").Cells(i, 2).Value)
                .SubItems(1) = Sheets("振込一覧").Cells(i, 4).Value
                .SubItems(2) = Sheets("振込一覧").Cells(i, 5).Value
                .SubItems(3) = Sheets("振込一覧").Cells(i, 6).Value
                .SubItems(4) = Format(Sheets("振込一覧").Cells(i, 7).Value, "#,##0")
                .SubItems(5) = Format(Sheets("振込一覧").Cells(i, 14).Value, "#,##0")
                .SubItems(6) = Format(Sheets("振込一覧").Cells(i, 13).Value, "#,##0")
                .SubItems(7) = Sheets("振込一覧").Cells(i, 12).Value
                .SubItems(8) = Format(Sheets("振込一覧").Cells(i, 8).Value, "#,##0")
                End With
          Next

        '年月日の部分を降順に表示させる
         .SortKey = .ColumnHeaders("_nengaltupi").INDEX - 1
         .SortOrder = lvwDescending
         .Sorted = True
・
・
・
End Sub

< 使用 Excel:Excel2016、使用 OS:Windows10 >


>一定行数で切って
↑しか考慮してないですが
 For i = 3 To Sheets("振込一覧").Range("B" & Rows.Count).End(xlUp).Row
  もしも、iが300行を超えたらForを抜ける
 Next

としたらどうですか?

(もこな2) 2021/05/02(日) 11:31


追加で。

そもそも全行読み込む必要があるのがよくわかりません。
「B列は日付が入力してある行です。」ということですから、それを条件に読み込む必要があるのか否か条件分岐すればよかったりしませんか?

 (ユーザーに期間を指定させるとか、システム的に直近○か月とするとか)

(もこな2) 2021/05/02(日) 11:52


(もこな2)さん
返事ありがとうございます。
> (ユーザーに期間を指定させるとか、システム的に直近○か月とするとか)
こんなこと可能ですか? 可能であれば直近2ヶ月だけ表示させたいのですが
よろしくお願いします。
(nobu) 2021/05/02(日) 14:26

やってないけど、可能じゃないですか。
繰り返しになりますが、「B列は日付が入力してある行です。」なんですから本日の日付なり年月なりを条件にして処理分岐するだけでしょう?

提示されたコードを作成(もしくは理解)された方ならさして躓くとも思えませんが・・・

(もこな2) 2021/05/02(日) 18:13


>B列は日付が入力してある行です
>可能であれば直近2ヶ月だけ表示させたいのですが

2ヶ月前なら
  DateAdd("m",-2,Now)

これとB列の日付を比較して
  1)ループ中に途中で期日以前になったらループを終了させる判断
  2)最初からiを決めて実行
では ?
(白戸) 2021/05/02(日) 18:33


(もこな2)さん
ありがとうございます。

>提示されたコードを作成(もしくは理解)された方ならさして躓くとも思えませんが・・・
さして理解できてるわけでもなく、いつも見よう見まねで四苦八苦しておりちょっと編集
するたび悩んでおります。Web上の情報でいつもなんとかなる程度です。ですので
すみませんがご指導よろしくお願いします。
分岐とは 3を日付(過去2ヶ月)に置き換えるのでしょうか?

        With ListView1
            For i = 3 To Sheets("振込一覧").Range("B" & Rows.Count).End(xlUp).Row
(nobu) 2021/05/02(日) 18:34

(白戸)さん
ありがとうございます。
ちょっと色々Web検索しましたが難しいですね

(nobu) 2021/05/02(日) 19:17


 横から失礼。

 >以前 ListViewについて質問した者ですが
 関係があるかもしれないので、URLを示して下さい。

 全く同じコードをネットで探しても無いでしょうね。
 (むろんそれぞれの要素技術については当然ありますよ。)
 だから、全く同じものを探す努力と言うより、示された方針に沿ってご自分でトライするしかないですよ。

     2ヶ月前の日付 = (ここは既に指摘がありました)
     For i = 3 To Sheets("振込一覧").Range("B" & Rows.Count).End(xlUp).Row
         もし i行目の日付が 2ヶ月前の日付 以前なら
             Forを抜ける
         もし終わり
         '以下に、必要な処理を書く
     Next
 というようなことですよね。
 どの辺が不明ですか?
 不明点を明確にすることが大切です。 それをクリアーするための第一歩ですから。
(γ) 2021/05/02(日) 20:15

(γ)さん ありがとうございます。
以下の感じではないですか?
     Dim rowsData
     rowsData = DateAdd("m", -2, Now)
     For i = 3 To Sheets("振込一覧").Range("B" & Rows.Count).End(xlUp).Row
         If i <= rowsData Then
            Exit For
         End If
         ★'以下に、必要な処理を書く
以下をどの様に、入れ込むのか?
元文
            For i = 3 To Sheets("振込一覧").Range("B" & Rows.Count).End(xlUp).Row
            With .ListItems.Add(Text:=Sheets("振込一覧").Cells(i, 2).Value)
                .SubItems(1) = Sheets("振込一覧").Cells(i, 4).Value
                .SubItems(2) = Sheets("振込一覧").Cells(i, 5).Value
                .SubItems(3) = Sheets("振込一覧").Cells(i, 6).Value
                .SubItems(4) = Format(Sheets("振込一覧").Cells(i, 7).Value, "#,##0")
                .SubItems(5) = Format(Sheets("振込一覧").Cells(i, 14).Value, "#,##0")
                .SubItems(6) = Format(Sheets("振込一覧").Cells(i, 13).Value, "#,##0")
                .SubItems(7) = Sheets("振込一覧").Cells(i, 12).Value
                .SubItems(8) = Format(Sheets("振込一覧").Cells(i, 8).Value, "#,##0")
                End With
          Next
(nobu) 2021/05/02(日) 20:48

>If i <= rowsData Then
この意味を日本語で説明してください。

>必要な処理を書く
「必要な処理」はあなたが知っているはずですが。
あなたが提示したコードですよ?

それから以前のスレッドのURLを書いて下さい。

(γ) 2021/05/02(日) 21:03


>>If i <= rowsData Then
>この意味を日本語で説明してください。
説明ですが入力データよりrowsDataが大きいと考えたのですが・・・

>「必要な処理」はあなたが知っているはずですが。
>あなたが提示したコードですよ?
iとの連続性が良く理解できていません

以前の質問は、ListViewに関してですが読み込みに時間の件です。
https://www.excel.studio-kazu.jp/kw/20201118192655.html

よろしくお願いします。
(nobu) 2021/05/02(日) 21:14


>If i <= rowsData Then
i って何ですか?行番号じゃないですか?
rowsData = DateAdd("m", -2, Now)
で定義したrowsDataは何ですか?
それは比較するのに適したものですか?

まずはここだけ。

(γ) 2021/05/02(日) 21:39


■1
>さして理解できてるわけでもなく、いつも見よう見まねで四苦八苦しており
このトピックで質問されたこととは関係ないですが、それならば先に現状のコードを理解できるようになってないとマズイでしょう。
前トピックのように速度を気にするのは、正直そのあとのことのようにおもいます。

あと、この掲示板内で他の記事にリンクを張るには、記事番号を二重角括弧で囲めばよいです

 (γさんからはURLを示せといわれているので、今回の提示は間違いではないとは思いますが)
[[20201118192655]]『ListView1読み込みスピードアップするには』(nobu)

■2
こちらも質問とは関係しませんが「m_ShownFlag」は何のために用いてますか?
前トピックを含めててみても、現状提示されているコードを見る限りでは必要性がわかりません。

■3
このトピックのほうは、たぶんこんな感じじゃないですかね。

    Sub 研究用()
        Dim カウンタ As Long
        Dim MySH As Worksheet
        Dim 基準日 As Date
        Dim i As Long
        '〜省略〜

        Set MySH = Sheets("振込一覧")
        基準日 = DateAdd("m", -2, Date) '←時刻まで見る必要が無ければ「Date」のほうがよくないですか?

        For i = 3 To MySH.Range("B" & MySH.Rows.Count).End(xlUp).Row
            '▼【読み込み件数に制限をかける部分】
            'もしも、カウンタが300を超えていたら、メッセージを表示してForを抜ける
                'メッセージを表示してForを抜ける
            'もしもの話はおしまい

            '▼【B列の値で条件分岐する部分】
            'もしも、MySH.Cells(i, 2).Valueの値が「基準日」以降なら取り込む
                With ListView1.ListItems.Add(Text:=MySH.Cells(i, 2).Value)
                    '〜省略〜
                End With
                カウンタ = カウンタ + 1
            'もしも、の話はおしまい
        Next i

        '〜省略〜
    End Sub

(もこな2) 2021/05/02(日) 22:53


書き忘れ。

データ元の「振込一覧」シートがB列基準で【降順】に並べてあるのならγさんが指摘されたように「 Forを抜ける」でよいと思いますが、前トピックを含めてみても、どのように並んでいるか私には読み取れなかったので、全行をチェックするような方法にしています。

(もこな2) 2021/05/02(日) 23:01


>降順にした状態で最近入力したデータ
と言う記述だったので、途中でExit Subすればよいと思いました。

[[20210427014111]]
もHNは違っても、同じかたでしょ?
m_ShownFlagなどというFlagが偶然一致することはありえません。HNは統一して下さい。
あなたにとってメリットはないです。

書き方が悪かったかもしれませんが、「必要な処理」などというものは今のものでいいんです。
その最初で、B列にある日付と、今から2ヶ月前の日を比較して、それより古くなった段階で
ループから抜けるだけの話なんです。

B列のフォーマットが不明ですが、Data型であれば、2ヶ月前日付(Date型)と比較可能ですし、
もし、B列の日付が文字列なら、DateValue関数でDate型に変換してから比較すればいい。

いずれにしても、ネットにあるコードを形式的に真似るのではなく、
中身を理解して、自分の頭で作る努力をしないと、コードを書けるようにはなれません。
変数名も中身を理解していれば、rowsData などとはならない。行には関係しないものですよ。

私はここまでとさせていただきます。

(γ) 2021/05/02(日) 23:42


(もこな2)さん
データ元振込一覧は
     A        B          C        D        E   ・ ・    S
1
2   NO.    年月日               振込先    ・ ・
3  1  令和2年3月8日         ○○銀行
4    2    令和2年3月8日         ○□銀行
5    3    令和2年4月8日         □△銀行
B列に日付表示形式で和暦にしています 2021/3/8入力 上から下へ順次昇順(古い順)

>このトピックのほうは、たぶんこんな感じじゃないですかね。
もしも部分ハードル高いですね ちょっと考えてみます。

300行で区切るよりやはり直近2ヶ月がよい思います。
(nobu) 2021/05/02(日) 23:44


(γ)さん
>いずれにしても、ネットにあるコードを形式的に真似るのではなく、
>中身を理解して、自分の頭で作る努力をしないと、コードを書けるようにはなれません。
>変数名も中身を理解していれば、rowsData などとはならない。行には関係しないものですよ。
仰るとおりとは思いますが、常日頃から関わっていないとなかなか一度理解しても
難しいです。やはり三日坊主では駄目ですね
ありがとうございました。
(nobu) 2021/05/02(日) 23:53

■4
>大体利用する行数が300行(降順にした状態で最近入力したデータ)あれば問題ない
と言っていて↓のように「ListView1」を並び替えしてるので、【データ元】が降順とは限らないかなぁと思ってました。
 With ListView1
   .SortKey = .ColumnHeaders("_nengaltupi").INDEX - 1
   .SortOrder = lvwDescending
   .Sorted = True

>上から下へ順次昇順(古い順)
つまり、データ元はB列をキーにして【昇順】に並んでいるのですね。
そうであれば↓のように、下から見ていけば「Exit For」戦法でも行けますね。

 For i = Sheets("振込一覧").Range("B" & Rows.Count).End(xlUp).Row To 3 Step -1

このようにすれば、全行見る必要もないですし、ListView1の並び替えもいらないので、速度を気にされるならこちらのほうが適切でしょう。

■5
>もしも部分ハードル高いですね ちょっと考えてみます。
何が分からないのかちょっと謎です。
B列には日付(シリアル値)が入っているのでしょう?基準日と比較して未満なのか以上なのか判定するだけじゃないですか。

    Sub 研究2()
        Dim 基準日 As Date
        基準日 = DateAdd("m", -2, Date)

        If "2021/05/03" >= 基準日 Then
            MsgBox "基準日以降です"
        Else
            MsgBox "基準日より前です"
        End If

        If "2020/05/03" >= 基準日 Then
            MsgBox "基準日以降です"
        Else
            MsgBox "基準日より前です"
        End If
     End Sub

■6
「研究用」の中にコメントで記述しましたが、「DateAdd("m",-2,Now)」で本当に大丈夫ですか?
今日実行したとして↓のような結果になりますけど、どちらが望む結果なのですか?

    Sub 研究3()
        Dim 基準日 As Date

        '▼Dateの場合
        基準日 = DateAdd("m", -2, Date)
        If "2021/3/3" >= 基準日 Then
            MsgBox "基準日以降です"
        Else
            MsgBox "基準日より前です"
        End If

        '▼Nowの場合
        基準日 = DateAdd("m", -2, Now)
        If "2021/3/3" >= 基準日 Then
            MsgBox "基準日以降です"
        Else
            MsgBox "基準日より前です"
        End If
    End Sub

■7
6と関連しますが「直近2ヶ月」とはどのようなイメージですか
今日実行したとして↓なら「2021/3/3」となるわけですが

 DateAdd("m", -2, Date)

正直↓のように今月を含む2か月(つまり「2021/04/01」以降)となるのが正しいような・・・

    Sub 研究4()
        Dim 基準日 As Date

        基準日 = DateAdd("m", -2, Date)
        MsgBox 基準日

        基準日 = DateSerial(Year(Date), Month(Date) - 1, 1)
        MsgBox 基準日

    End Sub

(もこな2) 2021/05/03(月) 01:02


(もこな2)さん
何度もありがとうございます。
>正直↓のように今月を含む2か月(つまり「2021/04/01」以降)となるのが正しいような・・・
そうなんですが2ヶ月の意味は、振込一覧のデータ入力は4月の段階で5月の振込日を
入力しており、4月末時点でListView1に表示します。よってこの時点において4月・5月分を見るためなので 今日現在は5月ですけどいいのですが4月末時点では vba文章に基準日、Dateを書き込んだ場合3月・4月が表示されてしまいませんか?

それと現在使用しているコードでOKなんですがListViewに表示される順番は振込一覧の表示順です 以下の並べ替え後の並び方が良好Noな状態です ※振込一覧の上から記入順です。

 With ListView1
   .SortKey = .ColumnHeaders("_nengaltupi").INDEX - 1
   .SortOrder = lvwDescending
   .Sorted = True

振込一覧の現在の作成すみ行数は2630行あり今後どんどん増えていきますので毎回ListView
に全て読み込むのが無駄な気がしましたので質問させていただきました。
以下の部分の 3を例えば2400などに変更すると表示速度もすこぶる軽快になりましたから
For i = 3 To Sheets("振込一覧").Range("B" & Rows.Count).End(xlUp).Row
説明がごちゃごちゃしてすみません。

(nobu) 2021/05/03(月) 02:39


■8
>そうなんですが2ヶ月の意味は、振込一覧のデータ入力は4月の段階で5月の振込日を入力しており、4月末時点でListView1に表示します。よってこの時点において4月・5月分を見るためなので 今日現在は5月ですけどいいのですが4月末時点では vba文章に基準日、Dateを書き込んだ場合3月・4月が表示されてしまいませんか?

えーっと・・・よくわかりません。
どんな時にどうなればいいのか【箇条書き】で示せませんか
【箇条書きの例】

 ・振込日=毎月10日
 ・マクロを実行した日が【2021/5/3】なら【2021/3/11〜2021/5/10】が対象
 ・マクロを実行した日が【2021/5/11】なら【2021/4/11〜2021/6/10】が対象

■9
>振込一覧の現在の作成すみ行数は2630行あり今後どんどん増えていきますので毎回ListViewに全て読み込むのが無駄な気がしましたので質問させていただきました。

何を説明したいのかわかりませんが、「研究用」で示しているように読み込み件数が一定を超えたときに制限し、残りはスキップすることも、条件に合致するものだけ読み込むことも(無論、両者の併用も)可能ですよ。

また、再三になりますがB列が何らかの順番に並んでいるなら「Exit For」で問題ないでしょう。

■10
>それと現在使用しているコードでOKなんですがListViewに表示される順番は振込一覧の表示順です 以下の並べ替え後の並び方が良好Noな状態です ※振込一覧の上から記入順です。

こちらもよくわかりません。

 ListView1.SortKey = ListView1.ColumnHeaders("_nengaltupi").INDEX - 1
         ↓
 ListView1.SortKey = 0

ってことですよね。何故回りくどい書き方にしてるのですか?
そして、【SortOrder = lvwDescending】ですから【降順】に並べ替えてますよね。
データ元は【昇順】に並んでいるとのことですから、振込一覧(シート)の表示順ではないでしょう。

さらに言うと、こちらも繰り返しになりますが、後ろの日付から拾っていけば、勝手に降順で並びますからそもそも並び替えの必要はないでしょう。

■11
すでに、前トピックで指摘されていることですが、「UserForm_Activate」で処理すべきことなんですか?「UserForm_Initialize」で一度だけ読み込めばいいような気がしてなりませんが・・・

(もこな2) 2021/05/03(月) 03:46


■8
内容説明ですが
・振込日毎月5日±3前後
・マクロ実行時というよりも元データ「振込一覧」が毎月20日前後に更新します
 この更新後の最新月と前月を表示したいです(常に最新月+前月でOKです)
■9
>何を説明したいのかわかりませんが、「研究用」で示しているように読み込み件数が一定>を超えたときに制限し、残りはスキップすることも、条件に合致するものだけ読み込む>ことも(無論、両者の併用も)可能ですよ。
併用ができれば最高の仕上がりです(変数300とか変更可能がいいですが)

■10
説明が悪かったかも知れません
振込一覧元データ

     A        B          C          D           E   ・ ・    S
1
2    NO.    年月日       登録NO     会社名       振込先    ・ ・
3    1  令和2年1月5日          いちご(株)  ○○銀行
4      2    令和2年1月5日          みかん(株)  ○□銀行
5      3    令和2年1月5日          (株)ばなな  □△銀行
・
・
2540 2538  令和3年4月5日          りんご(株)  ○○銀行
2241 2539  令和3年4月5日          ばなな(株)  ○○銀行
2242 2540  令和3年4月5日          みかん(株)  ○○銀行
・
・
2620 2618  令和3年5月6日          ぶどう(株)  ○○銀行
2621 2619  令和3年5月6日          もも(株)    ○○銀行
2622 2620  令和3年5月6日          すいか(株)  ○○銀行
2623 2621  令和3年5月6日          くり(株)    ○○銀行

降順コード無しの場合のListView表示
2020/1/5  いちご(株)  ○○銀行
2020/1/5  みかん(株)  ○□銀行
2020/1/5  (株)ばなな  □△銀行


2021/4/5  りんご(株)  ○○銀行
2021/4/5  ばなな(株)  ○○銀行
2021/4/5  みかん(株)  ○○銀行


2021/5/6  ぶどう(株)  ○○銀行
2021/5/6  もも(株)   ○○銀行
2021/5/6  すいか(株)  ○○銀行
2021/5/6  くり(株)   ○○銀行

降順コード有りの場合のListView表示(こちらが希望の表示です)
現在のコードでできています
2021/5/6  ぶどう(株)  ○○銀行
2021/5/6  もも(株)   ○○銀行
2021/5/6  すいか(株)  ○○銀行
2021/5/6  くり(株)   ○○銀行


2021/4/5  りんご(株)  ○○銀行
2021/4/5  ばなな(株)  ○○銀行
2021/4/5  みかん(株)  ○○銀行


2020/1/5  いちご(株)  ○○銀行
2020/1/5  みかん(株)  ○□銀行
2020/1/5  (株)ばなな  □△銀行
このように同一日付のグループは「振込一覧」で作成した順番で表示されソートされないままで表示します。
この通りでOKです入力順で変わってほしくないです。
■11
UserForm_Initializeで試してみます。
以前なにかでUserForm_Activateが良いような文章を見たことが合ったと思いずっとこのままでした
長々説明でまた、迷わせてしまうかも知れませんがよろしくお願いします。

(nobu) 2021/05/03(月) 05:27


■8のレスのレス
>振込日毎月5日±3前後
「±3前後」の意味が分かりません。

>元データ「振込一覧」が毎月20日前後に更新します。
以前のように、別ブックにあるのだったらファイルの更新日を取得するという手が使えましたが、今は同じブックのシートなんですよね?
何か更新日を取得できるヒントはありますか?(どこかのセルに更新日を入れておくルールがあるとか)

 ただ、「振込一覧」シートを更新したらマクロを実行するというルールなら、結局マクロ実行日でよいはずですが・・・

■9のレスのレス
既に示したとおりです。

■10のレスのレス
提示の例でいえば、2623、2622、2621、2620行目・・・のように下から読み込んでいけば

 2021/5/6  くり(株)   ○○銀行
 2021/5/6  すいか(株)  ○○銀行
 2021/5/6  もも(株)   ○○銀行
 2021/5/6  ぶどう(株)  ○○銀行
 ・
 ・
 2021/4/5  みかん(株)  ○○銀行
 2021/4/5  ばなな(株)  ○○銀行
 2021/4/5  りんご(株)  ○○銀行

のようになるといってるわけですが、これだと会社名や振込先の順番が逆になっちゃうので困るということが言いたいのですか?
そうであれば、「振込一覧」シートをB列基準で降順に並び替えてから、上から取り込めばok(ListView1のソートは不要)ですね。

■11のレスのレス
>以前なにかでUserForm_Activateが良いような文章を見たことが合ったと思い〜
時と場合によるでしょう。今回のケースでは、ユーザーフォームがアクティブになるたびにいちいち読込しなおす必要があるのか?って話です。
例えば、別のマクロで「振込一覧」シートを更新して、それをListView1に直ぐに反映させる必要があるとかであれば、Initializeだとちょっと問題ですよね。(それでもActivateイベントで処理すべきなのか疑問ですが)
いずれにせよ、既に指摘されていることですが、ネットで見かけた(質問掲示板で答えのあった)コードを鵜呑みにするのではなくちゃんと理解することが重要であるように思います。
(ちゃんと試してから質問すれば、ズレた質問にはなりませんし、たいていの人は答えてくれますよ。)

■12
提示されたようなコードを曲がりなりにも作られた方ならとっくにご存じでしょうが、念のためおいておきます。

 【ブレークポイント】
https://www.239-programing.com/excel-vba/basic/basic022.html
https://www.tipsfound.com/vba/01010

 【ステップ実行】
https://www.239-programing.com/excel-vba/basic/basic023.html
http://plus1excel.web.fc2.com/learning/l301/t405.html

 【イミディエイトウィンドウ】
https://www.239-programing.com/excel-vba/basic/basic024.html
https://excel-ubara.com/excelvba1/EXCELVBA486.html

 【ローカルウィンドウ】
https://excel-ubara.com/excelvba4/EXCEL266.html
http://excelvba.pc-users.net/fol8/8_2.html

(もこな2) 2021/05/03(月) 11:02


■8のレスのレス
>「±3前後」の意味が分かりません。
年末年始 大型連休 土日祝祭日などの関係です

>元データ「振込一覧」が毎月20日前後に更新します。
>以前のように、別ブックにあるのだったらファイルの更新日を取得するという手が使えましたが、今は同じブックのシートなんですよね?
何か更新日を取得できるヒントはありますか?(どこかのセルに更新日を入れておくルールがあるとか)
特にルールなどはないですね

 ■10のレスのレス
>のようになるといってるわけですが、これだと会社名や振込先の順番が逆になっちゃうの>で困るということが言いたいのですか? 
その通りです

■11のレスのレス
質問時、最初に提示したコード中

         .SortKey = .ColumnHeaders("_nengaltupi").INDEX - 1
         .SortOrder = lvwDescending
         .Sorted = True
・
・
・
End Sub
・・の部分に以下コードがあり
Initializeだと読み込み時アクティブにならなかったのでActivateイベントを採用しました

    Dim selIdx As Long
    selIdx = Val(Range("X2"))
    If selIdx = 0 Then selIdx = 4

        If .ListItems.Count >= selIdx Then
            .ListItems(selIdx).Selected = True
            ListView1.SetFocus
        End If

(もこな2)さんが熱心に見ていただいてありがたいのですが
レベルが高くなかなか理解できないです、もう少し単純に
3 を変数にできますか?
要するに最終行から以前300行ぐらいが表示されればいいのですが
2千数百行の読込でタイムラグが生じるから発想が至ったものですから

        With ListView1
           For i = 3 To MySH.Range("B" & Rows.Count).End(xlUp).Row
            With .ListItems.Add(Text:=MySH.Cells(i, 2).Value)
                .SubItems(1) = MySH.Cells(i, 4).Value
                .SubItems(2) = MySH.Cells(i, 5).Value
                .SubItems(3) = MySH.Cells(i, 6).Value
                .SubItems(4) = Format(MySH.Cells(i, 7).Value, "#,##0")
                .SubItems(5) = Format(MySH.Cells(i, 14).Value, "#,##0")
                .SubItems(6) = Format(MySH.Cells(i, 13).Value, "#,##0")
                .SubItems(7) = MySH.Cells(i, 12).Value
                .SubItems(8) = Format(MySH.Cells(i, 8).Value, "#,##0")
            End With
何度も申し訳ございませ
ちょっとこれから仕事で出かけなくては鳴りませんので、返答は夜になります
よろしくお願いします。
(nobu) 2021/05/03(月) 11:44

■13
>年末年始 大型連休 土日祝祭日などの関係です
えーっと・・よくわかりませんが、たとえば「2021/5/3」を基準に前後1ヶ月±3だとしたら、「2021/3/31〜2021/6/6」となりますが、そういうことを言いたいのですか?

>特にルールなどはないですね
それは困りましたね。
私の「■8のレスのレス」で「結局マクロ実行日でよいはずですが・・・」と書きましたがどうなのですか?
それもダメとなると、もうマクロの実行時にユーザーに指定してもらうのが手っ取り早いのではありませんか?

■14
>その通りです
では、

 (A) 私の「■10のレスのレス」で示したようにする
 (B) 「■3」で示したようにする

いずれかじゃないですかね。

■15
・トピ主の「■11のレスのレス」について
>・・の部分に以下コードがあり
>Initializeだと読み込み時アクティブにならなかったのでActivateイベントを採用しました
理解できません。何を期待したコードなんですか?
そして、何をアクティブにしたいのですか?

■15
>、もう少し単純に3 を変数にできますか?
意味不明です。

 For i = 3 To MySH.Range("B" & Rows.Count).End(xlUp).Row

↑は【i】という変数を3〜B列最終行の行番号になるまで、1ずつカウントアップさせてますよ。
(本当に理解(もしくは研究)してるなら、そんなことは言われずともでしょうが)

■16
>要するに最終行から以前300行ぐらいが表示されればいいのですが
>2千数百行の読込でタイムラグが生じるから発想が至ったものですから
正直めんどくさくなってきました。
もう、↓のようにしたらいいんじゃないですか?

 For i = WorksheetFunction.Max(3, Mysh.Range("B" & Rows.Count).End(xlUp).Row - 300) To Mysh.Range("B" & Rows.Count).End(xlUp).Row

(もこな2) 2021/05/03(月) 13:41


■13
・振込日毎月5日±3前後
 プラスマイナス3日間です 5月の場合は5/6日(銀行営業日)です
>私の「■8のレスのレス」で「結局マクロ実行日でよいはずですが・・・」と書きましたがどうなのですか?
はい「振込一覧」が、更新されなければマクロは実行しませんので
マクロ実行日でよいです。

■14
のようになるといってるわけですが、これだと会社名や振込先の順番が逆になっちゃうので困るということが言いたいのですか?
そうであれば、「振込一覧」シートをB列基準で降順に並び替えてから、上から取り込めばok(ListView1のソートは不要)ですね。
もこな2さんが示したとおりです。逆順になるのは困ると言いたかったんです

■15
前回起動時クリックした行をbookのセルに記録し。次回起動時前回のクリック行を
以下でアクティブにします。
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)

    Range("X2") = ListView1.SelectedItem.INDEX
End Sub

■16
混乱させてすみません。
>正直めんどくさくなってきました。
>もう、↓のようにしたらいいんじゃないですか?
希望通りです が
もこな2さんが言いたいのはここでは無いのも分かります(提示いただいたマクロ)
一生懸命分かるように導いてくれているにもかかわらず着いていけず申し訳ないです。
(nobu) 2021/05/03(月) 19:27


■17(トピ主の「■13」のレス)
では、【マクロ実行日】を基準にどのようなものを抽出したいのか、例のように箇条書きで説明して下さい。
【箇条書きの例】(再掲)
 ・振込日=毎月10日
 ・マクロを実行した日が【2021/5/3】なら【2021/3/11〜2021/5/10】が対象
 ・マクロを実行した日が【2021/5/11】なら【2021/4/11〜2021/6/10】が対象

■18(トピ主の「■14」のレス)
既に了解してます。何を説明したいのかよくわかりません。
(了解したから、対象でないものをスキップして取り込み終わってからListViewを並べ替えをするか、データ元を降順で並び替えてから条件に合わないものが出てきたら抜ければ、ListView側の並び替えは要らないですね。と言ってます)

■19(トピ主の「■15」のレス)
えーっと・・・それ↓と関係します?
>Initializeだと読み込み時アクティブにならなかったのでActivateイベントを採用しました

QueryCloseイベントで、X2セルに覚書しておくのなら、なおさら非アクティブになるだけではX2セルに出力しないので、なおさらInitializeで処理すべきだと思うんですが・・・・

まあ、X2セルに「ListView1.SelectedItem.INDEX」をメモしておくだけだと、前回とリスト(抽出範囲)が変わったら意味ないので根本的に変えないとダメじゃないですかね。

■20(トピ主の「■16」のレス)
別に混乱はしてないですが、言ってることがちぐはぐ(に思えますし)、ろくに試しもせず(のように思えます)聞いてこられているのでちょっとあきれてる感じです。
(ちょっと乱暴ないいぶりと感じられるようであればごめんなさい)

(もこな2) 2021/05/03(月) 20:47


    >Dim selIdx As Long
    >selIdx = Val(Range("X2"))
    >If selIdx = 0 Then selIdx = 4
    >    If .ListItems.Count >= selIdx Then
    >        .ListItems(selIdx).Selected = True
    >        ListView1.SetFocus
    >    End If
 このコードは初出ですね。
 後出しで条件増やしたら回答者がかわいそうですわ

 Activateに書くべきものはActivateに
 Initializeに書くべきものはInitializeに書くのです。
(GWどこにもいけない) 2021/05/03(月) 21:51

■21
>■17(トピ主の「■13」のレス)
>【マクロ実行日】を基準にどのようなものを抽出したいのか、例のように箇条書きで説明して下さい。
振込日毎月5日
マクロ実行日は通常振込日の前の月の15日〜25日になります。
マクロ実行日が【2021/4/20】なら【2021/4/1〜2021/5/31】が対象 ※原則4月分5月分です
マクロ実行日が【2021/5/20】なら【2021/5/1〜2021/6/30】が対象 ※原則5月分6月分です
要するに実行日の同月と次月となります。

■22
>■18(トピ主の「■14」のレス)

 2021/5/6  くり(株)   ○○銀行
 2021/5/6  すいか(株)  ○○銀行
 2021/5/6  もも(株)   ○○銀行
 2021/5/6  ぶどう(株)  ○○銀行
 ・
 ・
 2021/4/5  みかん(株)  ○○銀行
 2021/4/5  ばなな(株)  ○○銀行
 2021/4/5  りんご(株)  ○○銀行
のようになるといってるわけですが、これだと会社名や振込先の順番が逆になっちゃうので困るということが言いたいのですか? 
そうです逆順では困ります。

■23
>■19(トピ主の「■15」のレス)
>えーっと・・・それ↓と関係します?
>Initializeだと読み込み時アクティブにならなかったのでActivateイベントを採用しました
私の説明ですと益々混乱させてしまいそうなのでInitializeでいきます。

>まあ、X2セルに「ListView1.SelectedItem.INDEX」をメモしておくだけだと、前回とリス>ト(抽出範囲)が変わったら意味ないので根本的に変えないとダメじゃないですかね。
こちらは、マクロの実行後のデータをクリックし別帳票に転記する作業ですので前回どの
行をクリックしたかの確認用です。

■24
一応試しているつもりですが回答のスピードが速くついて行けていません。

(nobu) 2021/05/04(火) 01:24


なんか番号とられちゃいましたが、被るよりマシなのでそのまま進めます。

■25(■21のレス)
了解しましたけど、じゃぁ±3ってなんだったんですか?(興味本位で聞いてます)

ちなみに↓で確定でよいですね?(コロコロ条件変えられると面倒なので・・・・)
対象となるのはB列の日付が、マクロを実行した月の1日〜〜翌月の末日までのもの

■26(■22のレス)
既にそれは了解しています。
繰り返しになりますが、それ故に
 ・ループの中で条件に合うものだけ取り込むようにして、ListViewを並べ替えする
 ・先にシートのB列を並び替えてから、基準日より以前のデータが出てきたらループを抜ける
のどちらかだと言っています。(この説明3回目ですし、堂々巡りになっているので次から無視します)

■27(■23のレス)
>私の説明ですと益々混乱させてしまいそうなのでInitializeでいきます。
必要なコメントはしたつもりなので好きにしてください。

>前回どの行をクリックしたかの確認用です。
繰り返しになりますが、出力されるのは「ListView1.SelectedItem.INDEX」です。シートの行ではありません。
1ヶ月ずれただけで、先月のListView1の何番目を選んでいたかなんて情報意味ないと思いますよ。
(ひと月の中で何日かにわけて作業するということなら意味はあるのかもしれませんが、それならシートの方に処理済みフラグでも立てておいたほうが、よっぽど建設的じゃないですかね)
まぁ、こちらも好きにしてください。

■28(■24のレス)
そうですか。あまりそうは感じられませんが、そこを詰めてもしょうが無いので、テストはされているということで了解しました。
ちなみに、テスト(検証)の結果↓の答えはどうなりましたか?

 ■2 「m_ShownFlag」は何のために用いてますか?
    (★ご自身が書いたコードです。意味は理解してるのですよね?)

 ■5 何が分からないのかちょっと謎です。
      B列には日付(シリアル値)が入っているのでしょう?
      基準日と比較して未満なのか以上なのか判定するだけじゃないですか。
    (★理解できましたか?)

 ■6 〜どちらが望む結果なのですか?
    (★今となっては論点が変わってきましたが、何を言いたいかわかりましたか?)

■29
埒があかないので参考に提示します。
完成品のプレゼントではありませんから、きちんとステップ実行して研究のうえ必要な部分だけご自身のコードに組み込んでください。
(結果として同じになったならしょうが無いですが、理解せず丸写ししてそのまま使うのはダメですよ)

【Exit For】作戦

    Option Explicit
    Private Sub UserForm_Initialize()
        Dim MySH As Worksheet
        Dim 開始日 As Date, 終了日 As Date
        Dim カウンタ As Long
        Dim i As Long
        Set MySH = ThisWorkbook.Worksheets("振込一覧")

        Stop 'ブレークポイントの代わり

        '▼マクロを実行した日を元に、開始日と終了日を取得
        開始日 = DateSerial(Year(Date), Month(Date), 1)
        終了日 = DateSerial(Year(Date), Month(Date) + 2, 0)

        '▼シートの方を並び替え
        With MySH.Sort
            .SortFields.Clear
            .SortFields.Add2 Key:=Range("B2"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
            .SetRange MySH.Range("A2:S" & MySH.Cells(Rows.Count, "B").End(xlUp).Row)
            .Header = xlYes
            .Apply
        End With

        '▼ListViewのヘッダ行などを設定
        With ListView1
            .View = lvwReport
            .LabelEdit = lvwManual
            .HideSelection = False
            .AllowColumnReorder = True
            .FullRowSelect = True
            .Gridlines = True
            .ColumnHeaders.Add , "_nengaltupi", "年月日", 80, lvwColumnLeft
            .ColumnHeaders.Add , "_hurikomisaki", "振込先", 180, lvwColumnLeft
            .ColumnHeaders.Add , "_koumei", "銀行名", 100, lvwColumnLeft
            .ColumnHeaders.Add , "_sitenmei", "支店名", 80, lvwColumnLeft
            .ColumnHeaders.Add , "_siharaikingaku", "振込金額", 105, lvwColumnRight
            .ColumnHeaders.Add , "_anzen", "会費", 80, lvwColumnRight
            .ColumnHeaders.Add , "_sousai", "相殺", 80, lvwColumnRight
            .ColumnHeaders.Add , "_utiwake", "内訳", 114, lvwColumnLeft
            .ColumnHeaders.Add , "_tesuuryou", "手数料", 70, lvwColumnRight
        End With

        '▼ListViewにデータを読み込む
        For i = 3 To MySH.Cells(MySH.Rows.Count, "B").End(xlUp).Row
            '▼B列に開始日より前が出るようになったら、その行以降は読み込まない(ループを抜ける)
            If MySH.Cells(i, "B").Value < 開始日 Then Exit For

            '▼カウンタが一定数を超えたら、警告してそれ以上読み込まない(ループを抜ける)
            If カウンタ > 4 Then
                MsgBox _
                    prompt:="対象件数が規定数を超えたため" & vbLf & "最初の5件だけ読み込みました", _
                    Buttons:=vbExclamation
                Exit For
            End If

            With ListView1.ListItems.Add(Text:=MySH.Cells(i, 2).Value)
                .SubItems(1) = MySH.Cells(i, 4).Value
                .SubItems(2) = MySH.Cells(i, 5).Value
                .SubItems(3) = MySH.Cells(i, 6).Value
                .SubItems(4) = Format(MySH.Cells(i, 7).Value, "#,##0")
                .SubItems(5) = Format(MySH.Cells(i, 14).Value, "#,##0")
                .SubItems(6) = Format(MySH.Cells(i, 13).Value, "#,##0")
                .SubItems(7) = MySH.Cells(i, 12).Value
                .SubItems(8) = Format(MySH.Cells(i, 8).Value, "#,##0")
            End With

            カウンタ = カウンタ + 1
        Next i
    End Sub

【全行巡回して必要なものだけ取り込む】作戦

    Option Explicit
    Private Sub UserForm_Initialize()
        Dim MySH As Worksheet
        Dim 開始日 As Date, 終了日 As Date
        Dim カウンタ As Long
        Dim i As Long
        Set MySH = ThisWorkbook.Worksheets("振込一覧")

        Stop 'ブレークポイントの代わり

        '▼マクロを実行した日を元に、開始日と終了日を取得
        開始日 = DateSerial(Year(Date), Month(Date), 1)
        終了日 = DateSerial(Year(Date), Month(Date) + 2, 0)

        '▼ListViewのヘッダ行などを設定
        With ListView1
            .View = lvwReport
            .LabelEdit = lvwManual
            .HideSelection = False
            .AllowColumnReorder = True
            .FullRowSelect = True
            .Gridlines = True
            .ColumnHeaders.Add , "_nengaltupi", "年月日", 80, lvwColumnLeft
            .ColumnHeaders.Add , "_hurikomisaki", "振込先", 180, lvwColumnLeft
            .ColumnHeaders.Add , "_koumei", "銀行名", 100, lvwColumnLeft
            .ColumnHeaders.Add , "_sitenmei", "支店名", 80, lvwColumnLeft
            .ColumnHeaders.Add , "_siharaikingaku", "振込金額", 105, lvwColumnRight
            .ColumnHeaders.Add , "_anzen", "会費", 80, lvwColumnRight
            .ColumnHeaders.Add , "_sousai", "相殺", 80, lvwColumnRight
            .ColumnHeaders.Add , "_utiwake", "内訳", 114, lvwColumnLeft
            .ColumnHeaders.Add , "_tesuuryou", "手数料", 70, lvwColumnRight
        End With

        '▼ListViewにデータを読み込む
        For i = 3 To MySH.Cells(MySH.Rows.Count, "B").End(xlUp).Row
            '▼カウンタが一定数を超えたら、警告してそれ以上読み込まない(ループを抜ける)
            If カウンタ > 4 Then
                MsgBox _
                    prompt:="対象件数が規定数を超えたため" & vbLf & "最初の5件だけ読み込みました", _
                    Buttons:=vbExclamation
                Exit For
            End If

            If MySH.Cells(i, "B").Value >= 開始日 And MySH.Cells(i, "B").Value <= 終了日 Then
                With ListView1.ListItems.Add(Text:=MySH.Cells(i, 2).Value)
                    .SubItems(1) = MySH.Cells(i, 4).Value
                    .SubItems(2) = MySH.Cells(i, 5).Value
                    .SubItems(3) = MySH.Cells(i, 6).Value
                    .SubItems(4) = Format(MySH.Cells(i, 7).Value, "#,##0")
                    .SubItems(5) = Format(MySH.Cells(i, 14).Value, "#,##0")
                    .SubItems(6) = Format(MySH.Cells(i, 13).Value, "#,##0")
                    .SubItems(7) = MySH.Cells(i, 12).Value
                    .SubItems(8) = Format(MySH.Cells(i, 8).Value, "#,##0")
                End With
                カウンタ = カウンタ + 1
            End If
        Next i

        ListView1.SortKey = 0
        ListView1.SortOrder = lvwDescending
        ListView1.Sorted = True
    End Sub

たぶん処理速度としては

 ・【Exit For】作戦
 ・【全行巡回して必要なものだけ取り込む】作戦
 ・【何でもいいから下から300件取り込む】作戦

の順で早いんじゃないですかね。(もとのデータ件数と対象のデータ件数によるでしょうが)

(もこな2) 2021/05/04(火) 04:34

微修正しました。

(もこな2) 2021/05/04(火) 10:12


(もこな2)さん
返事遅くなりました、何度も確認しながら検証させていただきました。
理解するにはまだほど遠いですが・・・

結果、今回【全行巡回して必要なものだけ取り込む】作戦 を利用させてください
【Exit For】作戦は、振込一覧シートをソートしているためか[現在約2,600行ほどですが月々増えていきます]
表示するまでに若干タイムラグがあるようです、またソートした状態のままでは都合が悪いです。次月の作業に対して一番古いデータが最下行になるので

>繰り返しになりますが、出力されるのは「ListView1.SelectedItem.INDEX」です。シートの行ではありません。
>1ヶ月ずれただけで、先月のListView1の何番目を選んでいたかなんて情報意味ないと思いますよ。
(ひと月の中で何日かにわけて作業するということなら意味はあるのかもしれませんが、それならシートの方に処理済みフラグでも立てておいたほうが、よっぽど建設的じゃないですかね)
↑こちらですが、意味ないですか?
ListViewクリックした行を判断(振込一欄を更新してしまえば意味ないですが)する方法が
ほか思いつかないのですがシートの方に処理済みフラグ立てるとは 今回振込一覧から取り込んだデータは、印刷帳票(転記し印刷実行)なのでフラグといっても難しくないですか?
とりあえず 報告です。
(nobu) 2021/05/07(金) 04:00


>を利用させてください
【再掲】
完成品のプレゼントではありませんから、きちんとステップ実行して研究のうえ必要な部分だけご自身のコードに組み込んでください。
(結果として同じになったならしょうが無いですが、理解せず丸写ししてそのまま使うのはダメですよ)

>↑こちらですが、意味ないですか?
おしゃっていることが理解できないですが好きにしてください。
(コードを実行する上で問題になるわけではなさそうですし)

(もこな2) 2021/05/07(金) 07:47


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.