• ベストアンサー

(VBA) 字幕の内容が複数行の場合、1行に集約化

現在、字幕翻訳(英語>日本)で字幕ファイル(テキストファイル)を補助ツールで テキストファイル内の特定文字列を他の文字列に置き換える作業を行っています。 その後、置き換え終了後のファイルをEXCELのシートに読み込ませているのですが 補助ツールでの処理をEXCEL(VBA)で処理できないか考えています。 字幕ファイル(SRT形式)は、  通し番号(連番)  字幕の表示時間(タイムコード)  字幕の内容(表示文字列=テキスト情報)  改行文字 '--------------------------------- SRTの例 1 00:05:00,400 --> 00:05:15,300 This is an example of a subtitle. 2 00:05:16,400 --> 00:05:25,300 This is an example of a subtitle - 2nd subtitle. 3 00:05:40,200 --> 00:05:41,0250 This is an example of a subtitle - 3rd subtitle. '----------------------------------- やりたい作業は、以下の作業です。 1)SRTの例の3番目のを見ると「字幕の内容」の部分の最後に改行コード有って 次の行に引き続き「字幕の内容」があります。 つまり、「字幕の内容」が複数行存在している。 この場合は、  文字列の最後の改行コードを半角スペースに置き換えて  1行の「字幕の内容」にコンバートする (1番目や2番目のように1行に) 結果、 This is an example of a subtitle - 3rd subtitle. Sheet1のA列にコンバート前のテキストファイルが読み込み済みであるとして 「字幕の内容」が複数行の部分を1行にするコードを摸索していますが どうも「字幕の内容」部分が複数行かをチェックする方法が思いつきません。 何かアドバイスがあればお願いします。 最終的には、SRTフォーマットで別シートに1行にした「字幕の内容」を書き出すようにしたい。 「字幕の内容」部分が複数行の場合、通常はあっても2行までと思われますが 3行目以降が無いとは言い切れないので2行固定では無い方向でお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • kkkkkm
  • ベストアンサー率65% (1633/2477)
回答No.6

データ量が多いのでしょうか。 Transpose関数は65537を超えるとエラーが出るという情報がありました。 セルアクセスに変更しようと思いましたが、データ量が多いと遅くなると思いますので最後に2次元配列に入れてTranspose関数を使わないようにしました。 変更点は、途中のjmojiをtmpに変更して最後にtmpのデータをjmojiに入れてます。 Sub Test2() Dim i As Long, j As Long, k As Long Dim lastRow As Long Dim tb As Variant Dim tmp() As String, jmoji As Variant k = 0 lastRow = Cells(Rows.Count, "A").End(xlUp).Row 'セルのデータを2次元配列に tb = Range(Cells(1, "A"), Cells(lastRow, "A")).Value For i = LBound(tb, 1) To UBound(tb, 1) If IsNumeric(tb(i, 1)) And Not IsEmpty(tb(i, 1)) Then ReDim Preserve tmp(k) '字幕はセクションの数値の2行あとのお約束なのでそこからはじめる For j = i + 2 To UBound(tb) 'いつまで続くのか分からないのでとりあえず最後まで 'とりあえず最後までだけど 'それまでにセクション区切りの空白があるお約束なので '途中のセクションは最後まで行かずにループを抜ける If IsEmpty(tb(j, 1)) Then Exit For End If '空白になるまで文字を連結する3rd subtitle.の前にスペースがあったのでそれを削除するためにTrim tmp(k) = tmp(k) & " " & Trim(tb(j, 1)) Next tmp(k) = Trim(tmp(k)) i = j k = k + 1 End If Next Columns("B").ClearContents ReDim jmoji(1 To UBound(tmp) + 1, 1 To 1) For i = 1 To UBound(tmp) + 1 jmoji(i, 1) = tmp(i - 1) Next Cells(1, "B").Resize(UBound(jmoji, 1), 1).Value = jmoji End Sub

NuboChan
質問者

お礼

ステップ実行する事で原因が判明しました。 ステップ実行でローカルウインドウを観察すると セクションを分ける区切りを認識できないので jmojiに次から次へと文字列を加えているようです。 つまり  If IsEmpty(tb(j, 1)) Then を見直す必要があると思い If tb(j, 1) = "" Then に変更するとエラー無く上手く処理できました。 読み込むテキストファイルによるのか? 読み込んだ後の区切り記号の選定が難しいです。 テキストエディターから文字列群をA列にコピペする場合と FileSystemObjectオブゼクトでファイルを読み込む場合とでは 区切り文字が違うようです。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (6)

  • kkkkkm
  • ベストアンサー率65% (1633/2477)
回答No.7

> If tb(j, 1) = "" Then > に変更するとエラー無く上手く処理できました。 それはよかったです。 =""とIsEmptyは違うものと昔読んだ記憶があったのでコンマ一秒くらい考えたのですが、うまくいったしIsEmptyの方がカッコイイとか思ったのでIsEmptyにしてました。 =""の方が安全そうですね。

NuboChan
質問者

補足

>=""の方が安全そうですね たまたま、まぐれ当たりで上手くいっただけです。 空白セルの判別と言うので以下を参照しましたが 結局、=""とIsEmptyの違いは判りませんでした。 https://excel-ubara.com/excelvba4/EXCEL276.html 試しにテキストエディターからコピペした場合で同じコードを利用して処理してみましたが If tb(j, 1) = "" Then で、エラー無く処理できました。 (もちろん、 If IsEmpty(tb(j, 1)) Thenでもエラー無く処理できました。) 結論として、アドバイスと同じく=""を使う方が良さそうです。

全文を見る
すると、全ての回答が全文表示されます。
  • kkkkkm
  • ベストアンサー率65% (1633/2477)
回答No.5

もうし分けない、また訂正 出力したデータの頭に半角スペースが残ってましたので i = j k = k + 1 のところを jmoji(k) = Trim(jmoji(k)) i = j k = k + 1 に変更してください。 あと 現状では問題ないと思いますがセクションに入った後にReDimした方がいいと思うので。 For i = LBound(tb) To UBound(tb) ReDim Preserve jmoji(k) If IsNumeric(tb(i, 1)) And Not IsEmpty(tb(i, 1)) Then を For i = LBound(tb, 1) To UBound(tb, 1) If IsNumeric(tb(i, 1)) And Not IsEmpty(tb(i, 1)) Then ReDim Preserve jmoji(k)

NuboChan
質問者

お礼

すいません。 No1.のお礼で記載したコードに一部ミスがありました。 以下に変更済みです。 jmoji = Cells(tmp, "A").Offset(2) & " " & Cells(tmp, "A").Offset(3) & " " & Cells(tmp, "A").Offset(4) コード修正後にNo2のデータで試した結果 確かにご指摘のように3の範囲が抽出されませんでした。 原因調査後のコード修正を考える前にkkkkkmさんから直ぐに解決策のコードが出ましたので試した。 (No2>3>4>5の修正こみこみ) 結果、上手く3が抽出できない問題も無く希望の形式で抽出が完了しました。 これから、実際の字幕DATAで実際に検証を始めます。 少しお時間をください。

NuboChan
質問者

補足

実際の字幕で検証し始めましたが、以下のコードでエラー出ます。 Cells(1, "B").Resize(UBound(jmoji) + 1, 1).Value = WorksheetFunction.Transpose(jmoji) worksheetFunctionクラスのTransposeプロパティを取得できません。 どこかチェックすべき事項があればアドバイスお願いします。 Sub Test_kkkkm() Dim i As Long, j As Long, k As Long Dim lastRow As Long Dim tb As Variant Dim jmoji() As String k = 0 lastRow = Cells(Rows.Count, "A").End(xlUp).Row 'セルのデータを2次元配列に tb = Range(Cells(1, "A"), Cells(lastRow, "A")).Value For i = LBound(tb, 1) To UBound(tb, 1) If IsNumeric(tb(i, 1)) And Not IsEmpty(tb(i, 1)) Then ReDim Preserve jmoji(k) '字幕はセクションの数値の2行あとのお約束なのでそこからはじめる For j = i + 2 To UBound(tb) 'いつまで続くのか分からないのでとりあえず最後まで 'とりあえず最後までだけど 'それまでにセクション区切りの空白があるお約束なので '途中のセクションは最後まで行かずにループを抜ける If IsEmpty(tb(j, 1)) Then Exit For End If '空白になるまで文字を連結する3rd subtitle.の前にスペースがあったのでそれを削除するためにTrim jmoji(k) = jmoji(k) & " " & Trim(tb(j, 1)) Next jmoji(k) = Trim(jmoji(k)) i = j k = k + 1 End If Next Columns("B").ClearContents '1次元配列をセルに書き込むためにTranspose使う Cells(1, "B").Resize(UBound(jmoji) + 1, 1).Value = WorksheetFunction.Transpose(jmoji) End Sub

全文を見る
すると、全ての回答が全文表示されます。
  • kkkkkm
  • ベストアンサー率65% (1633/2477)
回答No.4

回答No.1の微妙な訂正です。 省略した形なので問題はないのですが よろしければ LBound(tb) To UBound(tb) を LBound(tb, 1) To UBound(tb, 1) にしておいてください。

全文を見る
すると、全ての回答が全文表示されます。
  • kkkkkm
  • ベストアンサー率65% (1633/2477)
回答No.3

回答No.2の訂正です。 現状だと 外の For i = LBound(tb) To UBound(tb) このループは 00:05:00,400 --> 00:05:15,300 This is an example of a subtitle.1 1rd subtitle. ここを見なくていい(jで回っているとこ)のに無駄に見ていますので k = k + 1 のところにi = j を追加してもらって i = j k = k + 1 最後の Cells(1, "C").Resize(UBound(jmoji), 1).Value = WorksheetFunction.Transpose(jmoji) を Cells(1, "C").Resize(UBound(jmoji) + 1, 1).Value = WorksheetFunction.Transpose(jmoji) に変更してください。

全文を見る
すると、全ての回答が全文表示されます。
  • kkkkkm
  • ベストアンサー率65% (1633/2477)
回答No.2

1 00:05:00,400 --> 00:05:15,300 This is an example of a subtitle. 1rd subtitle. 2 00:05:16,400 --> 00:05:25,300 This is an example of a subtitle - 2nd subtitle. 3 00:05:40,200 --> 00:05:41,0250 This is an example of a subtitle - 3rd subtitle. 3rd subtitle. 3rd subtitle. 4 00:05:40,200 --> 00:05:41,0250 This is an example of a subtitle - 4rd subtitle. 上記のデータでなぜか3の範囲が書き込まれずに This is an example of a subtitle. 1rd subtitle. This is an example of a subtitle - 2nd subtitle. This is an example of a subtitle - 4rd subtitle. こうなりました。 訂正箇所が分からないのでこちらで試してみてください。C列に書き込みます。 Sub Test() Dim i As Long, j As Long, k As Long Dim lastRow As Long Dim tb As Variant Dim jmoji() As String k = 0 lastRow = Cells(Rows.Count, "A").End(xlUp).Row 'セルのデータを2次元配列に tb = Range(Cells(1, "A"), Cells(lastRow, "A")).Value For i = LBound(tb) To UBound(tb) ReDim Preserve jmoji(k) If IsNumeric(tb(i, 1)) And Not IsEmpty(tb(i, 1)) Then '字幕はセクションの数値の2行あとのお約束なのでそこからはじめる For j = i + 2 To UBound(tb) 'いつまで続くのか分からないのでとりあえず最後まで 'とりあえず最後までだけど 'それまでにセクション区切りの空白があるお約束なので '途中のセクションは最後まで行かずにループを抜ける If IsEmpty(tb(j, 1)) Then Exit For End If '空白になるまで文字を連結する3rd subtitle.の前にスペースがあったのでそれを削除するためにTrim jmoji(k) = jmoji(k) & " " & Trim(tb(j, 1)) Next k = k + 1 End If Next Columns("C").ClearContents '1次元配列をセルに書き込むためにTranspose使う Cells(1, "C").Resize(UBound(jmoji), 1).Value = WorksheetFunction.Transpose(jmoji) End Sub

全文を見る
すると、全ての回答が全文表示されます。
  • kkkkkm
  • ベストアンサー率65% (1633/2477)
回答No.1

通し番号(連番)から始まって3行目(最初の字幕の内容)以降は、改行文字だけの行が出るまで前の行に追加し、改行文字だけの行が出たら次のセクションという感じでいけそうな気もしますがどうでしょう。

NuboChan
質問者

お礼

kkkkkmさん、お世話になります。 アドバイスありがとうございます。 試行錯誤して以下のコードでを考えてみました。 連番の行番号を配列に読み込んで 連番行の下に改行(EXCELでは””の行)がどこにあるかで  「字幕の内容」を連結すると言う思考です。 無駄が多いように思えますがいかがでしょうか ? Option Explicit Sub AddConsecutiveNumbers() Dim i As Long, j As Long Dim lastRow As Long Dim tb() As Variant Dim jmoji As String lastRow = Cells(Rows.Count, "A").End(xlUp).Row ReDim tb(lastRow) '通し番号の行(番号)を求める j = 0 For i = 1 To lastRow If Cells(i, "A").Value = Range("A1") + j Then tb(i) = Cells(i, "A").Row 'Debug.Print tb(i) j = j + 1 Else ' End If Next '---------------------------------------- Dim temp() As Variant ' emptyでない配列の数を数える j = 0 For i = LBound(tb) To UBound(tb) If Not IsEmpty(tb(i)) Then j = j + 1 End If Next i ' emptyでない配列をtemp()にコピー ReDim temp(1 To j) j = 0 For i = LBound(tb) To UBound(tb) If Not IsEmpty(tb(i)) Then j = j + 1 temp(j) = tb(i) End If Next i ' tb()を再構築 ReDim tb(1 To j) For i = LBound(tb) To UBound(tb) tb(i) = temp(i) Next i '----------------------------- Columns("B").ClearContents 'b列に字幕の内容のみ書き出し Dim tmp As Long j = 1 For i = 1 To UBound(tb) tmp = tb(i) If Cells(tmp, "A").Offset(2) <> "" And Cells(tmp, "A").Offset(3) = "" Then jmoji = Cells(tmp, "A").Offset(2) Cells(j, "B") = jmoji j = j + 1 ElseIf Cells(tmp, "A").Offset(3) <> "" And Cells(tmp, "A").Offset(4) = "" Then jmoji = Cells(tmp, "A").Offset(2) & " " & Cells(tmp, "A").Offset(3) Cells(j, "B") = jmoji j = j + 1 ElseIf Cells(tmp, "A").Offset(4) <> "" And Cells(tmp, "A").Offset(5) = "" Then jmoji = Cells(tmp, "A").Offset(2) & " " & Cells(tmp, "A").Offset(3) & Cells(tmp, "A").Offset(4) Cells(j, "B") = jmoji j = j + 1 End If Next End Sub

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • テキストファイルに複数行の文字列追加

    自動化する方法はないでしょうか。 テキストファイルは複数で内容もまちまちですが、 特定の文字列が出てくるので、そこに三行ほど同じ内容を追記します。 マクロとかを使うのでしょうか? よろしくお願いします。

  • 日本語字幕ファイル(smi)をsrtファイルに変換したいのですが、su

    日本語字幕ファイル(smi)をsrtファイルに変換したいのですが、subtitle workshopでsmiを読み込ませて、srtファイルで保存すればいいと、聞いたのですが、「読み込ませる」というのは。どういう作業になるのでしょうか? 「ファイルを開く」で開いてみたのですが、「ファイルが壊れているか、サポートされていないファイルです」と出てしまい、前に進みません。 教えて下さい。よろしくお願いいたします。

  • エクセル VBA 同じ内容のセルの行を合わせたい

    売上集計表があり、A列に全商品のコードが表示されてます。 毎日の売上商品のデータを商品コード別に数量を入力して同じ内容のセルの行の位置を合わせる作業を毎日行っています。 毎日の売上データはエクセルで集計されたデータを貼り付けて行っています。これをなんとかVBAで処理したいのですが、どうしたらいいのかわかりません。 内容としてはA列に全商品の商品コードが既に入力されています。 月のはじめは、B列とC列に一日の集計データそのまま貼り付けます。 A列の商品コードと同じ商品コードの行に合うまで空白のセルを挿入していきます。 次の日は、D列とE列、その次はF列とG列と右に貼り付けしていきます。 商品コードは約3000件、毎日の集計データ数は約500件です。 どうか教えてください。 完成例)   A列   B列   C列     D列    E列       F列    G列   H列   I列 商品コード    10/1分        10/2分            10/3分       10/4分・・・続く        商品コード 数量   商品コード 数量      商品コード数量 CZ1.000  CZ1.000   10    CZ1.000   20 CZ1.005                                CZ1.010  15   ←セルの挿入で CZ1.010  CZ1.010   30                    CZ1.020 30    下げる作業を CZ1.015                                CZ1.030  10 毎日行ってます。 CZ1.020  CZ1.020   11   CZ1.020    20       CZ1.040  40 CZ1.025 CZ1.030  CZ1.030   11   CZ1.030    10 よろしくお願いします。

  • テキストファイルの内容を1行ずつ大きく表示させたい

    テキストファイルの内容を1行分あるいは適当な長さずつ、大きく表示させるフリーソフトを探しています。 次の行の内容を見るためにはキーボードの矢印を使うといった様な操作が希望です。  海外の大学の講義を動画で見る時に使うのが目的です。つまりスクリプトは持っているので、それを字幕のように自分で操作してブラウザの下に出したいのです。 よろしくお願いします。

  • エクセルVBA 文字列複数行・列連続連結

    エクセルVBA 文字列複数行・列連続連結でお教え下さい A列に基本文字(縦順) B列~F列に複数行データー(文字・時間) 文字結合時に改行 例 A2&B2&改行&A3&C2&改行&A4&D2&改行・・・・・ 次のデーター行 A&B3&改行&A3&C3&改行&A4&D3&改行・・・・・ データーの最終行まで連続で このような複数行あるデーターの連続文字列連結をしたいのですが・・・ 文字列連結後は 1.指定セルに貼り付け 2.クリップボードに貼り付け 3.テキストファイルに保存 よろしくお願い致します

  • 複数行の文字列を変数として使う方法

    Excel2010 VBAを使っています。 ファイルAに AAA BBBB CCCCC DD ・・・ というように50行程度に渡って文字列が書かれています。 この文字列をファイルB(これも同じく文字列が書かれています)と合体させるプログラムを作っています。 このプログラムをほかのPCでも使用したいのですが、 xlsmファイルとともにファイルAも同時にコピーする必要があり不便です。 ファイルAの内容を標準モジュールの中に保存したいのですが どのようにすれば良いでしょうか? dim a(50) a(0) = "AAA" a(1) = "BBBB" a(2) = "CCCCC" a(3) = "DD" ・・・ というように配列として保存しておけば、これができるのですが、 いちいち、ダブルクオテーションマークでくくって 上記のようなコードを書くのが面倒です。 例えば、 a = "AAA BBBB CCCCC DD ・・・" のように複数行に渡る文字列を変数として用いたいのですが このようなことは可能でしょうか?

  • .srtの文字化けを修正したい

    お世話になります。 ・使用OS Windows11 Home ・バージョン 22H2 メモ帳を立ち上げて字幕を作っていて、 拡張子を.srtに変更して保存をしていました。 .srtの拡張子のまま、内容を加筆・修正・保存を繰り返していたんですが、 先日、誤って削除してしまい、ゴミ箱からも完全に削除してしまいました。 翌日に削除したことに気づき、 MyRecoverというフリーソフトを使用して、 そのファイルを復元したんですが、 開いてみると文字化けしていました。 その.srtファイルを開いて、 ファイル→開く→文字コードをUTF-8に変更→開く 上記をやってみましたがダメでした。 拡張子を.txtに変えてからもやってみましたが、結果は同じでした。 そこで以下の2点を教えていただけるとありがたいです。 1.この文字化けをどうすれば元の文字列(日本語)に戻せるでしょうか 2.削除したファイルを文字化けしないで元に戻せるフリーソフトはあるでしょうか。 あるようでしたら教えてほしいです。 宜しくお願い致します。

  • エクセルの複数行の文字列を…

    エクセルに箇条書きにされている文字列を一つのセルにまとめたいのですが簡単な方法はありますか? 状態と致しまして、1カテゴリ 1.A欄に1行の文字列 2.B欄に3行の文字列 3.C欄に5行の文字列 4.D欄に3行の文字列 5.E欄に空欄 6.F欄に3行の文字列 上記内容は例となりますのでこの限りではありません。 この状態でA~Fの欄を1行にしたいのですが? 罫線で区切られカテゴリは複数あります。 内容がばらばらなので行が固定していません。 簡単に出来る方法を教えて下さい。

  • テキストボックスの内容(複数行)をリストへ

    テキストボックスの内容(複数行)をリストボックスへ1行表示にするにはどうすれば良いのでしょうか? replaceにてvbcrlf(改行文字?)を置き換えしようとしても無理でした。 ご教授お願いします。

  • 字幕ファイルsrtの開き方

    Windows7です。 メモ帳のテキスト入力で作成したsrtファイルの開き方お願いします。 (作成方法は字幕内容をテキスト入力後拡張子srtで保存) srt右クリックしても「プログラムから開く」が出てきません。 尚コントロールパネルの「既定のプログラム」の中に拡張子srtありません。

専門家に質問してみよう