[[20230612201742]] 『スペースを起点に改行。』(パック) ページの最後に飛ぶ

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

 

『スペースを起点に改行。』(パック)

お世話になります。

下記についてご相談があります。

スペースを起点に、データを改行したいのですが
まず仕様をご説明します。

仕様
全角80桁(△スペース含む)
20桁以内なおかつ20桁に一番近いスペースを起点に改行して(20桁ちょうどを含む)
分割したポイントの先頭が△スペースの場合△スペースを消去

結果が必ず、4行(データが少ない場合下記のようになる)

例1(対応済み)

編集前
ああああああああああああああああああああいいいいいいいいいいいいいいいいいいいいううううううううううう

デバックプリントでは改行を表示してます。

結果イメージ
1行目
ああああああああああああああああああああ
2行目
いいいいいいいいいいいいいいいいいいいい
3行目
ううううううううううう
4行目
確保エリア

例2(対応済み)

下記のパターンの場合、すべての領域にスペースがない場合
先頭から20桁ごとに分割。
編集前
ああああああああああああああああああああいいいいいいいいいいいいいいいいいいいいううううううううううううううううううううええええええええええええええええええええ
結果イメージ
1行目
ああああああああああああああああああああ
2行目
いいいいいいいいいいいいいいいいいいいい
3行目
うううううううううううううううううううう
4行目
ええええええええええええええええええええ

例3
下記のパターンの場合、8桁以降を起点に
改行させた場合
20桁以内に住所を途中で分割させないエリア(スペース)がない為)
例2と同じ処理方法に現状なります。(先頭から20桁ごとに分割)

編集前
あああ△いいい△0ハハ0ハ00−000ハハハハハハハハハハハハ

結果イメージ
1行目
あああ△いいい△0ハハ0ハ00−000ハ 改行
2行目
ハハハハハハハハハハハ 改行
3行目
確保エリア
4行目
確保エリア

希望結果
(例3の編集前を下記のようにしたい)

1行目
あああ△いいい△ 改行(20桁以内のスペースで改行)
2行目
0ハハ0ハ00−000ハハハハハハハハハ 改行(20桁以内にスペースがないので20桁で分割)
3行目
ハハハ 改行(20桁以内の残りの文字)
4行目
確保エリア

現在例3の結果イメージのように
例2と同じ処理方法で
単純に先頭から20桁ずつ改行する設定にしているのですが
希望結果のように
先頭から20桁以内の最終スペースにで改行して
次の行で、20桁以内にスペースがない場合
希望結果のように20桁で分割する
設定にしたいのですが、アドバイス頂けないでしょうか。
因みに、他のコードを生かしつつ
対応したいですが・・・

イメージ的には3行目のエリアでスペースがない場合も
希望結果と同じ考えになります。

1行名で改行できる場合20桁以内の近いスペースで改行
2行目で改行できる場合20桁以内の近いスペースで改行
3行目で改行できない場合20桁で分割
4行目エリアにデータがない場合確保エリア

下記の変数を切り替えれば
実行結果が3パターン確認できます。

ご返信が遅れる場合がありますが、アドバイス頂けると
助かります。

ご説明が分かりにくいかもしれません。
お手数おかけしますがよろしくお願いいたします

Sub main()

Dim tmp As String
Dim iMax As Long
Dim jMax As Long
Dim kCount As Long
Dim tmpLen As Long
Dim 住所Fs As String
Dim errchk As Long

errchk = 0

Const 住所漢字桁数max As Long = 20
Const 住所漢字行数max As Long = 4

Static tmp住所() As String
Static 住所(0 To 3) As String

'*********************************************************************
'* 変数
'*********************************************************************

'例1
'
'送付先住所漢字 = "ああああああああああああああああああああいいいいいいいいいいいいいいいいいいいいううううううううううう"
'
'例2
'
'送付先住所漢字 = "ああああああああああああああああああああいいいいいいいいいいいいいいいいいいいいううううううううううううううううううううええええええええええええええええええええ"

'例3

送付先住所漢字 = "あああ△いいい△0ハハ0ハ00−000ハハハハハハハハハハハハ"

 Const 住所Fs漢字 As String = " "

    住所Fs = 住所Fs漢字
    tmp = 送付先住所漢字
    iMax = 住所漢字桁数max
    jMax = 住所漢字行数max

  tmp = RTrim(tmp)
  '文字列tmp内のスペース数をカウントし配列要素数を決定する
  kCount = cnt_str(tmp, 住所Fs)

  ReDim tmp住所(0)
  For I = 0 To 3
    住所(I) = ""
  Next I

  tmp住所 = Split(tmp, 住所Fs)

  tmpLen = 0   '行に格納されている文字列の長さ
  j = 0        '行カウンタ
  For I = 0 To kCount
    If (debug_mode = 1) Then Debug.Print tmp住所(I)

    '文字列の長さが桁を超えたら改行する
    If ((tmpLen + Len(tmp住所(I))) > iMax) Then
      tmpLen = 0
      j = j + 1
      If (j > jMax - 1) Then
        errchk = 2
        GoTo err:
      End If
    End If

    住所(j) = 住所(j) & tmp住所(I)
    If (Len(住所(j)) < iMax) Then 住所(j) = 住所(j) & 住所Fs
    tmpLen = Len(住所(j))
  Next I

'正常処理

  If (debug_mode = 1) Then Debug.Print ("*" & 住所(0) & "*")
  tmpOut = 住所(0)
  For I = 1 To 3
    tmpOut = tmpOut & "改行" & 住所(I)
    If (debug_mode = 1) Then Debug.Print ("*" & 住所(I) & "*")
  Next I

'エラー処理
err:

  For I = 0 To kCount
    If (Len(tmp住所(I)) > iMax) Then errchk = 1  '桁数オーバーフロー
  Next I
  If (errchk = 1 Or errchk = 2) Then

    tmpOut = ""
    tmpPos = 1
    jtmp = 0 '要素数
    Do While (tmpPos <= Len(tmp))
      tmpLen = iMax
      If (Len(tmp) - tmpPos < iMax) Then tmpLen = Len(tmp) - tmpPos + 1
      tmpOut = tmpOut & Mid(tmp, tmpPos, tmpLen) & "改行"

      tmpPos = tmpPos + tmpLen
      jtmp = jtmp + 1
    Loop
    If (Mid(tmpOut, Len(tmpOut), 1) = "改行") Then
      tmpOut = Mid(tmpOut, 1, Len(tmpOut) - 1)
    End If
    If (jtmp = 2) Then tmpOut = tmpOut & "改行" & "改行"
    If (jtmp = 3) Then tmpOut = tmpOut & "改行"
  End If

Debug.Print tmpOut

End Sub

Function cnt_str(strTmp As String, Fs As String) As Long

j = 0
If (Len(strTmp) > 0) Then

  For I = 1 To Len(strTmp)
    If (Mid(strTmp, I, 1) = Fs) Then
      j = j + 1
    End If
  Next I
  cnt_str = j
Else
  cnt_str = -1
End If

End Function

< 使用 Excel:Excel2019、使用 OS:Windows11 >


 こういうことでしょうか?
 仕様を勘違いしていたら、そちらで修正してください。

 Sub test()
     Const mSpace As String = " "   '全角スペース
     Dim 住所$, adrs$, s20$
     Dim pos&
     Dim k&
     ReDim ans(1 To 4) As String     '区切り後の住所
     '例1
     '住所 = "ああああああああああああああああああああいいいいいいいいいいいいいいいいいいいいううううううううううう"
     '例2
     '住所 = "ああああああああああああああああああああいいいいいいいいいいいいいいいいいいいいううううううううううううううううううううええええええええええええええええええええ"
     '例3
     '住所 = "あああ いいい 0ハハ0ハ00−000ハハハハハハハハハハハハ"
     '例4
     '住所 = "1234567 901234567 901234567 901234567 901234567 901234567 901234567 901234567 90"

     adrs = 住所
     For k = 1 To 3
         s20 = Left(adrs, 20)
         pos = InStrRev(s20, mSpace) '20文字以内の最後の全角スペースの位置
         If pos = 0 Then             '全角スペースがなければ
             ans(k) = s20
             adrs = Mid(adrs, 21)
         Else                        '全角スペースがあれば
             ans(k) = Left(adrs, pos)
             adrs = Mid(adrs, pos + 1)
         End If
     Next
     ans(4) = adrs  '残りをすべて書き込むものとした。

     '結果確認
     For k = 1 To 4
         Debug.Print Len(ans(k)); ; ans(k)
     Next
 End Sub

 なお、変数の宣言もれといったコンパイルエラーが出ないものを提示するようにしてください。
(xyz) 2023/06/13(火) 06:26:26

    adrs = 住所
    For k = 1 To 3
        s20 = Left(adrs, 20)
        pos = InStrRev(s20, mSpace)    '20文字以内の最後の全角スペースの位置
        If pos = 0 Then pos = 20       '全角スペースがなければ20文字に
        ans(k) = Left(adrs, pos)
        adrs = Mid(adrs, pos + 1)
    Next
    ans(4) = adrs
 こう書くべきだったかな。
(xyz) 2023/06/13(火) 11:45:18

ご提示ありがとうございます。
またご確認てきておりません。

>なお、変数の宣言もれといったコンパイルエラーが出ないものを提示するようにしてください。

少し時間がかかりますが、上記のパターンをご提示します。

>仕様を勘違いしていたら、そちらで修正してください。

ご提示いただいたコードを理解していないと
修正はできませんが、参考になります。
ありがとうございます。

(パック) 2023/06/13(火) 12:22:42


 >少し時間がかかりますが、上記のパターンをご提示します。
 今後ということで結構です。提示には及びません。

 >ご提示いただいたコードを理解していないと修正はできません
 当然ですよ。
(xyz) 2023/06/13(火) 12:45:41

変数のパターンはしばらくお待ちください。
1点ご質問があります。
デバックプリントの値を
実際のデータで対応したいときに
私が、ご提示したコードですと
送付先住所漢字の値を
tmpoutとして割り当てれば結果が求められたのですが
ご提示いただいた
 Len(ans(k))を
tmpoutのように
結果として割り当てると
実行エラー9
インデックス範囲が有効範囲にありませんとなります。
tmpoutのように値を割り当てたい場合、アドバイスいただけると
助かります。
説明が不十分でしたら申し訳ございません。

(パック) 2023/06/14(水) 08:29:02


因みに、ご提示させて、頂いた改行という変数が、実際のデータのカンマに
割り当てられ、データを4行に分割する形になります。言い忘れていて申し訳ございません。
(パック) 2023/06/14(水) 09:26:40

 配列変数ansを最終結果の文字列にする方法、ということですか?

 私でしたら、
 Join(ans,vbLf)と文字列に変換して、
 それを一つのセルに書き出しますね。

 他のことでしたら、ご自分でやって下さい。
 4つのセルに入れるのであれば、繰り返しを使えばよいわけですし。
 もし詰まったら、続けて再質問して、
 他の回答者さんの回答をお待ちください。

(xyz) 2023/06/14(水) 09:45:38


ご連絡ありがとうございます。joinで対応出来ました。助かりました。変数はお待ち下さい。
(パック) 2023/06/14(水) 10:31:49

 >変数はお待ち下さい。
 どういうことですか?
(xyz) 2023/06/14(水) 10:42:12

変数の宣言もれといったコンパイルエラーが出ないものを提示するようにしてください。

すいません。上記の件はコードのことでしたか。
変数のパターンを提示する認識でしたので・・・

(パック) 2023/06/14(水) 11:19:35


 コンパイルエラーが出るようなコード提示は遠慮下さい、ただし次回以降で結構。という積りで書きました。

 普通は
 Option Explicit
 をモジュールの先頭に書きます。
 こうしておけば、変数宣言せずに変数を使うとコンパイルエラーになります。
 つまらない綴りの間違いなどがあれば、自動で検出してくれるので、
 多くの皆さんはこれを利用しているはずです。

http://officetanaka.net/excel/vba/beginner/06.htm

 を参考にしてください。
 また、そこに記載のとおり、
 オプション設定により、自動的にOption Explicitを挿入することができますから、
 一度だけ設定すれば、あとは気にする必要もありません。
 結構基本的ですが、役に立つTipsです。

 色々なパターンの検証は、ご自分で実行してください。
(xyz) 2023/06/14(水) 11:42:30

 > 自動的にOption Explicitを挿入する
 とは、moduleを新たに作った時に、という意味です。
 既存のmoduleには手で入れるしかありません。

 念のため。

(xyz) 2023/06/14(水) 11:49:47


(xyz)様。リンクのご提示と、アドバイスありがとうございます。
参考にさせていただきます。変数を20パターンぐらい用意して、
コードを調整させて頂いてます。どうもありがとうございました。
(パック) 2023/06/14(水) 16:28:32

コメント返信:

[ 一覧(最新更新順) ]


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