[[20190108200305]] 『シーケンス生成について。』(ヤイリ) ページの最後に飛ぶ

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

 

『シーケンス生成について。』(ヤイリ)

お世話になります。
下記のコードで

Bセルに

0100104184
0100104184
0100104184
0100104184
0100500180
0100500180
0100500180
0100500180
0100500180
0100512347

という文字列があった場合

Aセル,Bセル
1,0100104184
1,0100104184
1,0100104184
1,0100104184
2,0100500180
2,0100500180
2,0100500180
2,0100500180
2,0100500180
3,0100512347

とBセルの文字列が変わったタイミングで
シーケンスが繰り上がるのですが
これを

Aセル,Bセル
1-1,0100104184
1-2,0100104184
1-3,0100104184
1-4,0100104184
2-1,0100500180
2-2,0100500180
2-3,0100500180
2-4,0100500180
2-5,0100500180
3-1,0100512347

と結果を出したいのですが
可能でしょうか。
お手数ですがよろしくお願いします。

Sub main()

Dim buf As Variant

    Dim i As Long

    Dim rowToWrite As Long
    Dim lastRow As Long
    Dim valToProc As Variant

    lastRow = Range("B1").End(xlDown).Row

    valToProc = Cells(1, 1).Resize(lastRow, 2).Value

    i = 1
    valToProc(1, 1) = i

    For rowToWrite = 2 To lastRow
        If valToProc(rowToWrite, 2) <> valToProc(rowToWrite - 1, 2) Then
            i = i + 1
        End If
        valToProc(rowToWrite, 1) = i
    Next rowToWrite

    Cells(1, 1).Resize(lastRow, 2).Value = valToProc
End Sub

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


枝番用の変数を用意し

valToProc(rowToWrite, 2) <> valToProc(rowToWrite - 1, 2)

が真の場合は、1にリセット、偽の場合は、+1するとよいのではありませんか。

(マナ) 2019/01/08(火) 20:38


アドバイスどうもありがとうございます。
変数を用紙した場合の
真と偽の条件判定の方法がよくわからないので
ですが・・・

別で切り分けて
枝番をCセルに表示することはできるのですが。

Sub main()

Dim buf As Variant

    Dim i As Long
    Dim j As Long
    Dim rowToWrite As Long
    Dim lastRow As Long
    Dim valToProc As Variant

    lastRow = Range("B1").End(xlDown).Row

    valToProc = Cells(1, 1).Resize(lastRow, 2).Value

    i = 1
    valToProc(1, 1) = i

    For rowToWrite = 2 To lastRow
        If valToProc(rowToWrite, 2) <> valToProc(rowToWrite - 1, 2) Then
            i = i + 1
        End If
        valToProc(rowToWrite, 1) = i
    Next rowToWrite

    Cells(1, 1).Resize(lastRow, 2).Value = valToProc
 increment = 1
  Cells(1, 3) = increment
  ex = Range("B" & Rows.Count).End(xlUp).Row
  For j = 2 To ex
    If Cells(j, "B") = Cells(j - 1, "B") Then
      increment = increment + 1
    Else
      increment = 1
    End If
    Cells(j, "c") = increment
  Next

    End Sub

(ヤイリ) 2019/01/09(水) 09:59


Sub main()
    Dim c As Range
    For Each c In Range("B:B").SpecialCells(2)
        c.Offset(, -1).Value = "_" & WorksheetFunction.CountIf(Range("B1:B" & c.Row), c.Value)
        c.Offset(, -1).Value = WorksheetFunction.CountIf(Range("A1:A" & c.Row), "*_1") & c.Offset(, -1).Value
    Next c
End Sub
(mm) 2019/01/09(水) 10:44

>真と偽の条件判定の方法がよくわからないので
>ですが・・・

現在のコードを理解できていますか?

        If valToProc(rowToWrite, 2) <> valToProc(rowToWrite - 1, 2) Then
            i = i + 1
            increment = 1
        else
            increment = increment+1
        End If

(マナ) 2019/01/09(水) 18:47


(mm)さん。コードご提示ありがとうございます。助かりました。
(マナ)さん。アドバイスどうもありがとうございます。
勉強になりました。
またセル表示ではなく、配列操作でご質問するかもしれませんので
その際はよろしくお願いいたします。
(ヤイリ) 2019/01/10(木) 10:18

お世話になっております。
まだコードがよく理解できていないところも
あるのですが
例えば、Bセルの値が

変数(暗証番号)に入っている
値だったとして

0100104184
0100104184
0100104184
0100104184
0100500180
0100500180
0100500180
0100500180
0100500180
0100512347

VBAで結果として

1-1
1-2
1-3
1-4
2-1
2-2
2-3
2-4
2-5
3-1

値をグループ連番として取得できる
サンプルコードがあれば助かるのですが・・・
宜しくお願いします。
(ヤイリ) 2019/01/11(金) 12:00


質問が理解できていません。
元のコードと同じようにしたいということでしょうか?

これではだめでしたか。

        If valToProc(rowToWrite, 2) <> valToProc(rowToWrite - 1, 2) Then
            i = i + 1
            increment = 1
        else
            increment = increment+1
        End If

(マナ) 2019/01/11(金) 18:34


分かりにくくて大変失礼しました。
この先もうまく伝わるかどうかわかりませんが・・・

話をご説明すると長くなるし、伝わりにくいのですが
VBAでCSVで配列を読み込み→編集→書き出し
の作業を行う際に
セルに取得したAの値を
tmp = Cells(変数, "A")で

csvに書き出していたのですが
数件だと問題ないのですが

10000レコードを超えると
エクセルが応答しなくなり書き出せなくなります。

そこで、セルは一切使用せず

別件でご提示頂いた
[[20181202100907]]
『tmpの書き出しについて。』
ようにサンプルを頂けたらと思いまして。

これで伝わったかどうか分かりませんが・・・

因みに実際のコードは、モジュールが
いくつも分かれており
コードも多いですし
個人的なものではないので
ご提示できないのでサンプルがあればと思いまして。

理解できないようでしたら無視してください。
お手数おかけします。

(ヤイリ) 2019/01/11(金) 19:54


>tmp = Cells(変数, "A")で

1セルずつ書き込むから時間がかかるのであって
元もコードようにすれば、10000行でも瞬時だと思います。

これを試してみましたか?

        If valToProc(rowToWrite, 2) <> valToProc(rowToWrite - 1, 2) Then
            i = i + 1
            increment = 1
        else
            increment = increment+1
        End If

(マナ) 2019/01/11(金) 21:07


アドバイスどうもありがとうございます。

  >これを試してみましたか?

というのは下記のコード

 Sub main()

Dim buf As Variant

    Dim i As Long
    Dim j As Long
    Dim rowToWrite As Long
    Dim lastRow As Long
    Dim valToProc As Variant

    lastRow = Range("B1").End(xlDown).Row

    valToProc = Cells(1, 1).Resize(lastRow, 2).Value

    i = 1
    valToProc(1, 1) = i

    For rowToWrite = 2 To lastRow
        If valToProc(rowToWrite, 2) <> valToProc(rowToWrite - 1, 2) Then
            i = i + 1
        End If
        valToProc(rowToWrite, 1) = i
    Next rowToWrite

    Cells(1, 1).Resize(lastRow, 2).Value = valToProc
 increment = 1
  Cells(1, 3) = increment
  ex = Range("B" & Rows.Count).End(xlUp).Row
  For j = 2 To ex
    If Cells(j, "B") = Cells(j - 1, "B") Then
      increment = increment + 1
    Else
      increment = 1
    End If
    Cells(j, "c") = increment
  Next

    End Sub

を修正して
ご提示いただいたコードを
加えるという認識でしょうか?

If valToProc(rowToWrite, 2) <> valToProc(rowToWrite - 1, 2) Then

            i = i + 1
            increment = 1
        else
            increment = increment+1
        End If

それでしたら
理解しきれてないので、申し訳ございませんが
試しておりません。

(ヤイリ) 2019/01/11(金) 23:13


では、最初の質問のコードを使用した場合
データが10000行でエクセルが応答しなくなることがありますか。

(マナ) 2019/01/12(土) 10:01


 >では、最初の質問のコードを使用した場合
 >データが10000行でエクセルが応答しなくなることがありますか。 

ご連絡ありがとうございます。
最初の質問のコードを使用した場合
tmp = Cells(変数, 1) & "-" & Cells(変数, 3)で
10000行以上でtmpに書き出した場合
応答しなくなります。
(ヤイリ) 2019/01/13(日) 08:12


誤解させたようです。

では、最初の質問のコードを「実行」した場合
データが10000行以上でエクセルが応答しなくなることがありますか。
セルに書き込んでいるのに、瞬時に終わりませんか。

のつもりでした。

(マナ) 2019/01/13(日) 09:11


Sub main2()
    Dim i As Long
    Dim rowToWrite As Long
    Dim lastRow As Long
    Dim valToProc As Variant
    Dim tmp As Variant
    Dim j As Long

    lastRow = Range("B1").End(xlDown).Row
    valToProc = Cells(1, 1).Resize(lastRow, 2).Value
    For rowToWrite = 1 To lastRow
        If tmp <> valToProc(rowToWrite, 2) Then
            i = i + 1
            j = 1
            valToProc(rowToWrite, 1) = i & "-" & j
            tmp = valToProc(rowToWrite, 2)
        Else
            j = j + 1
            valToProc(rowToWrite, 1) = i & "-" & j
        End If
    Next rowToWrite
    Cells(1, 1).Resize(lastRow, 2).Value = valToProc
End Sub

(ピンク) 2019/01/13(日) 11:32


(マナ)さん。
そういうことですか。
tmpに書き出さずに
セルに表示するだけでも応答しなくなります。
因みに3000レコードに減らしても
応答なしです。
コードの書き方に問題があったのでしょうか。
(ヤイリ) 2019/01/13(日) 12:15

補足ですが、単体で10000レコードで
セル表示だけですと
一瞬で表示できますね。
(ヤイリ) 2019/01/13(日) 12:29

>補足ですが、単体で10000レコードで
>セル表示だけですと
>一瞬で表示できますね。

ということは、解決すべきは枝番と全く関係ないのでは?

(マナ) 2019/01/13(日) 14:59


そうですね。
2019/01/10(木) 10:18に、投稿させて頂いた、
セル表示ではなく配列操作についてご質問させて
下さい。とお伝えした話につながった
ということに結果なってしまったと思います。

(ヤイリ) 2019/01/13(日) 15:31


言葉が足らないかもしれませんので、
補足ですが、配列操作というのは、
Bセルの配列は一切使用せず、
CSVデータの配列に対して、判定した値を
tmpの値として書き出したいので、
サンプルがあればと思いまして。
話がややこしくて申し訳ございませんでした。
(ヤイリ) 2019/01/13(日) 15:43

話が噛み合っていません。

>補足ですが、単体で10000レコードで
>セル表示だけですと
>一瞬で表示できますね。

↑であるなら、何が問題なのですか?
問題がないのであれば、なぜ、

>Bセルの配列は一切使用せず、

ということになるのでしょうか。
枝番は、ピンクさんのコードで解決ですよね。

過去の質問(別HNでの質問も含めて)目を通してみましたが
どこまで理解できているのでしょうか。
今回のほうが、簡単な内容に思えるのですが…

>tmpに書き出さずに
>セルに表示するだけでも応答しなくなります。
>因みに3000レコードに減らしても
>応答なしです。
>コードの書き方に問題があったのでしょうか。

具体的なコードを示さずに、質問されても
どう答えてよいか困ります。

(マナ) 2019/01/13(日) 16:21


 まず(ピンク)さん。
 サンプルコードご提示ありがとうございます。
参考にさせていただきます。

 >具体的なコードを示さずに、質問されても
 >どう答えてよいか困ります。 

(マナ)さん。
困惑させて申し訳ございません。
中盤で記載させていただきました通り

 因みに実際のコードは、モジュールが
いくつも分かれており
コードも多いですし
個人的なものではないので
ご提示できないのでサンプルがあればと思いまして。
とお伝えしております。
理解できないようでしたら無視してください。 
ともご報告させていただいております。

作業の効率を考えて
実際の本データは200000レコードを超えると思いますので
一気にvsdから
読み込み→編集→書き出しして
出力したかったのです。

長い間お付き合いくださり
大変参考になりました。
過去の内容ももう一度チェックしてみます。
コメント
どうもありがとうございました。

(ヤイリ) 2019/01/13(日) 16:47


コメント返信:

[ 一覧(最新更新順) ]


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