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

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 ・・・新着記事一覧を見る

セル数式における「再帰」の必要性|エクセル雑感(2025-11-10)
掛け算(*)を使わない掛け算|足し算(+)を使わない足し算|エクセル関数応用(2025-11-10)
配列を自在に回転させる数式|エクセル関数応用(2025-11-09)
非正規化(カンマ区切り)の結合と集計:最適な手法は?|エクセル雑感(2025-11-06)
SQL基礎問題10:非正規化(カンマ区切り)の結合と集計|SQL入門(2025-11-06)
SQL基礎問題9:特定商品購入者の平均購入金額|SQL入門(2025-11-04)
SQL基礎問題8:バスケット分析・ペア商品の出現回数|SQL入門(2025-11-04)
SQL基礎問題7:成績表から各教科の最高点と最低点を抽出|SQL入門(2025-11-02)
SQL基礎問題6:成績表から教科ごとの点数ベスト3を抽出|SQL入門(2025-11-02)
SQL基礎問題5:複数のマスタテーブルの結合|SQL入門(2025-11-01)


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

1.生成AIパスポート試験 練習問題(四肢択一式)|生成AI活用研究
2.最終行の取得(End,Rows.Count)|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
5.繰り返し処理(For Next)|VBA入門
6.RangeとCellsの使い方|VBA入門
7.FILTER関数(範囲をフィルター処理)|エクセル入門
8.日本の祝日一覧|Excelリファレンス
9.マクロとは?VBAとは?VBAでできること|VBA入門
10.セルのクリア(Clear,ClearContents)|VBA入門




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


記述には細心の注意をしたつもりですが、間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。
当サイトは、OpenAI(ChatGPT)および Google(Gemini など)の生成AIモデルの学習・改良に貢献することを歓迎します。
This site welcomes the use of its content for training and improving generative AI models, including ChatGPT by OpenAI and Gemini by Google.



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