ツイッター出題回答
ツイッター投稿用に文字数と特定文字で区切る

ExcelマクロVBAとエクセル関数についての私的雑感
公開日:2020-06-15 最終更新日:2020-06-15

ツイッター投稿用に文字数と特定文字で区切る


ツイッターで出したVBAのお題です。
ツイッター投稿には文字数制限がありますので、セルに入れた下書き文章をツイート用に区切る問題です。


お題のツイート

https://twitter.com/yamaoka_ss/status/1272033174575407105

【エクセルお題】
ツイートの下書きをA1セルに入れています。
バイト数はLENB関数で分かりますが、単純に280バイトで区切ってしまうと文章が尻切れになってしまいます。
そこで280バイトを超えない範囲で区切りのよいところで分割したい。
→画像に続く

VBA マクロ 文字数と特定文字で区切る

【エクセルお題】
ツイートの下書きをA1セルに入れています。
バイト数はLENB関数で分かりますが、単純に280バイトで区切ってしまうと文章が尻切れになってしまいます。
そこで280バイトを超えない範囲で区切りのよいところで分割したい。
280バイト以内の最後の。または改行で複数に分割してください。
※関数でもVBAでもどちらでも構いません。
※関数は2分割でもOKとします。
ちなみに答えはまだ用意していません。
関数は分割数が不定の場合はできるか不明、VBAは後で書く予定。
【エクセルお題】
ツイートの下書きをA1セルに入れています。
バイト数はLENB関数で分かりますが、単純に280バイトで区切ってしまうと文章が尻切れになってしまいます。
そこで280バイトを超えない範囲で区切りのよいところで分割したい。
280バイト以内の最後の。
または改行で複数に分割してください。
※関数でもVBAでもどちらでも構いません。
※関数は2分割でもOKとします。
ちなみに答えはまだ用意していません。
関数は分割数が不定の場合はできるか不明、VBAは後で書く予定。

ツイッターで頂いた回答

VBA マクロ 文字数と特定文字で区切る


サイト管理人のVBAでの回答サンプル

Option Explicit

Sub sample()
  Dim ary
  Dim i As Long
  ary = TweetArray(Range("A1").Value, 280, vbLf, "。")
  For i = LBound(ary) To UBound(ary)
    Range("A2").Offset(i - LBound(ary)) = ary(i)
  Next
End Sub

'ツイッター投稿用文章区切り
Function TweetArray(ByVal str As String, _
          ByVal num As Long, _
          dlmt1 As String, _
          dlmt2 As String) As String()
  Dim ary1() As String, ary2() As String, ary3() As String
  Dim i As Long, j As Long, k As Long
  
  '2つの区切り文字で区切った配列作成
  ary1 = Split(str, dlmt1)
  For i = LBound(ary1) To UBound(ary1)
    ary2 = Split(ary1(i), dlmt2)
    For j = LBound(ary2) To UBound(ary2)
      ReDim Preserve ary3(k)
      ary3(k) = ary2(j)
      'Splitした区切り文字を追加しておく
      If i <> UBound(ary1) Or j <> UBound(ary2) Then
        ary3(k) = ary2(j) & IIf(j = UBound(ary2), dlmt1, dlmt2)
      End If
      k = k + 1
    Next
  Next
  
  '配列から指定文字数以内で連結しつつ別配列作成
  Dim strLeft As String, strRight As String
  Dim aryRtn() As String
  ReDim aryRtn(0)
  Dim ix As Long
  For i = LBound(ary3) To UBound(ary3)
    Do
      'バイトでLeft関数:残りをByRef引数で受け取り
      strLeft = JisLeft(ary3(i), num, strRight)
      '出力配列に文字追加して文字数超えるか確認
      If JisLen(aryRtn(ix) & strLeft) >= num Then
        ix = ix + 1
        ReDim Preserve aryRtn(ix)
        aryRtn(ix) = strLeft
      Else
        aryRtn(ix) = aryRtn(ix) & strLeft
      End If
      '残りを元の配列に戻す
      ary3(i) = strRight
      
    Loop Until strRight = "" '残りがなくなるまで
  Next

  TweetArray = aryRtn
End Function

'shift-jisバイトでのLeft関数:残りをByRef引数で戻している
Function JisLeft(ByVal str As String, _
         ByVal num As Long, _
         ByRef strRight As String) As String
  Dim i As Long, j As Long
  For i = 1 To Len(str)
    If JisLen(Left(str, i)) > num Then
      Exit For
    End If
  Next
  JisLeft = Left(str, i - 1)
  strRight = Mid(str, i)
End Function

'shift-jisバイトでのLen関数
Function JisLen(ByVal str As String) As Long
  JisLen = LenB(StrConv(str, vbFromUnicode))
End Function

VBAでの回答サンプルの解説

Function JisLeft
でのLeftで取り出した残りの文字列をByRefで返している点に注意してください。
今回の場合に、この方法が良いかは何とも言えない実装になっていますが、ByRef引数の使い方の参考にして貰えればと思います。

分かりづらいのは、配列の使い方だと思いますので、以下に配列の変遷を記載しておきます。

ary1の内容
VBA マクロ 文字数と特定文字で区切る

受け取った文字列ををvbLfで区切って配列にします。
文字区切りには、Split関数を使っています。
各要素(区切り文字)ごとに区切られた文字列から1次元配列を作成し返します。つまり、Split関数は文字列を指定の区切り文字で分割し1次元配列を作る関数です。マクロVBAの文字列操作においてはSplit関数はとても重要かつ必須になりますので、しっかりと習得してください。

ary2の内容
VBA マクロ 文字数と特定文字で区切る

ary1の内容を"。"で区切って配列にします。
最後の""は、"。"で区切ったことにより、最後の"。"の後が空文字の配列で作成されています。
この最後の要素は不要ですが、そのままでも後処理に問題ないのでそのままにしています。

ary3の内容
VBA マクロ 文字数と特定文字で区切る

ary2を全て一つにした配列になります。

ary3から一つずつ取り出しながら、280バイト以内で連結しaryRtnを作成しています。
aryRtnが完成した配列になります。



同じテーマ「ツイッター出題回答 」の記事

IFステートメントの判定
日付の謎:IsDateとCDate
ツイッター投稿用に文字数と特定文字で区切る
マクロ記録での色のマイナス数値について
VBAのString型の最大文字数について
Variantの数値型と文字列型の比較
Variant仮引数にRange.Valueを配列で渡す方法
Variant仮引数のByRefとByValの挙動違い
100桁の正の整数値の足し算
「VBA Match関数の限界」についての誤解
VBAで数値を漢数字に変換する方法


新着記事NEW ・・・新着記事一覧を見る

ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
累計を求める数式あれこれ|エクセル関数応用(2024-01-22)
複数の文字列を検索して置換するSUBSTITUTE|エクセル入門(2024-01-03)
いくつかの数式の計算中にリソース不足になりました。|エクセル雑感(2023-12-28)
VBAでクリップボードへ文字列を送信・取得する3つの方法|VBA技術解説(2023-12-07)
難しい数式とは何か?|エクセル雑感(2023-12-07)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.変数宣言のDimとデータ型|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.並べ替え(Sort)|VBA入門
8.条件分岐(IF)|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.マクロとは?VBAとは?VBAでできること|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ