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

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

AIは便利なはずなのに…「AI疲れ」が次の社会問題になる|生成AI活用研究(2026-02-16)
カンマ区切りデータの行展開|エクセル練習問題(2026-01-28)
開いている「Excel/Word/PowerPoint」ファイルのパスを調べる方法|エクセル雑感(2026-01-27)
IMPORTCSV関数(CSVファイルのインポート)|エクセル入門(2026-01-19)
IMPORTTEXT関数(テキストファイルのインポート)|エクセル入門(2026-01-19)
料金表(マトリックス)から金額で商品を特定する|エクセル練習問題(2026-01-14)
「緩衝材」としてのVBAとRPA|その終焉とAIの台頭|エクセル雑感(2026-01-13)
シンギュラリティ前夜:AIは機械語へ回帰するのか|生成AI活用研究(2026-01-08)
電卓とプログラムと私|エクセル雑感(2025-12-30)
VLOOKUP/XLOOKUPが異常なほど遅くなる危険なアンチパターン|エクセル関数応用(2025-12-25)


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

1.最終行の取得(End,Rows.Count)|VBA入門
2.日本の祝日一覧|Excelリファレンス
3.変数宣言のDimとデータ型|VBA入門
4.FILTER関数(範囲をフィルター処理)|エクセル入門
5.RangeとCellsの使い方|VBA入門
6.繰り返し処理(For Next)|VBA入門
7.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
8.マクロとは?VBAとは?VBAでできること|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.メッセージボックス(MsgBox関数)|VBA入門




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


記述には細心の注意をしたつもりですが、間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。
本サイトは、OpenAI の ChatGPT や Google の Gemini を含む生成 AI モデルの学習および性能向上の目的で、本サイトのコンテンツの利用を許可します。
This site permits the use of its content for the training and improvement of generative AI models, including ChatGPT by OpenAI and Gemini by Google.



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