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

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ステートメントの判定

ツイッターでIfステートメントの書き方が話題になっていたのを見て、結構いろいろな要素があるということで、ちょっと意地悪な問題にしてみました。お題のツイート https://twitter.com/yamaoka_ss/status/1271402726174277632 VBA問題 さて、いくつが表示されるでしょう…
日付の謎:IsDateとCDate
ツイッターで出したVBAのお題です。エクセルにおける日付のちょっと不思議な挙動についての、ちょっと変わった、ちょっと意地悪な問題です。お題のツイート https://twitter.com/yamaoka_ss/status/1271776939343110146 【VBA問題】 画像のVBAはエラーになる事がある…
ツイッター投稿用に文字数と特定文字で区切る
マクロ記録での色のマイナス数値について
ツイッターで出したVBAのお題です。マクロの記録で文字色などの色を指定するとマイナス数値で記録される場合がありますが、このマイナス数値は何かを問う問題です。お題のツイート https://twitter.com/yamaoka_ss/status/1272119270026051587 【エクセル問題】 マクロの記…
VBAのString型の最大文字数について
ツイッターで出したVBAのお題です。String型はVBAリファレンスでは、「可変長文字列は、最大で約20億(2^31)文字を格納できます。」と書かれています。これについて、本当は何文字まではいるのかについての問題です。
Variantの数値型と文字列型の比較
ツイッターで出したVBAのお題です。Variant型は、どんなデータ型も入れることができます。具体的なデータ型の代わりに使用することで、より柔軟にVBA記述ができるようになります。ただしその一方で、少々特殊な挙動もあり、使いこなすにはそれなりの知識が必要になる場合もあります。
Variant仮引数にRange.Valueを配列で渡す方法
ツイッターで出したVBAのお題です。Variant型は、どんなデータ型も受け入れることができます。RangeオブジェクトのValueを配列で受け取るにはVariant変数が必要です。ただし、実引数にRangeオブジェクトを直接指定する場合には注意が必要です。
Variant仮引数のByRefとByValの挙動違い
ツイッターで出したVBAのお題です。Variant型は、どんなデータ型も入れることができてしまいます。具体的なデータ型の代わりに使用することで、より柔軟にVBA記述ができるようになります。ただしこの便利さゆえに、逆に注意しなければならない挙動もあります。
100桁の正の整数値の足し算
ツイッターで出したVBAのお題です。数の単位に「無量大数」というものがあります。VBAでこの無量大数の足し算をするにはどうしたら良いでしょうか。そこで、100桁の正の整数の足し算をVBAで実現してみましょう。
「VBA Match関数の限界」についての誤解
ツイッターで出したVBAのお題です。発端はエゴサーチからです。(笑) 「教えて!goo」で引用されていたのを見つけました。あちこちで引用されているのは見かけることはあるのですが、以下ではよく言うディスられているような文章を見かけました。
VBAで数値を漢数字に変換する方法
ツイッターで出したVBAのお題です。算用数字を漢数字に変換するVBAです。滅多に必要になるものではないのに、なぜこんな問題を出したかと言うと、最近シリーズで書き始めた「Excel将棋」で必要になったからです。


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

エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
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)


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

1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.並べ替え(Sort)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.ひらがな⇔カタカナの変換|エクセル基本操作




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


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


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