VBAで時間を正規表現するパターンを教えてください

このQ&Aのポイント
  • VBAで時間を正規表現するパターンを教えてください。セル中の文字列に混在する時間の形式に統一性がありません。
  • 探しても上記のパターンを網羅するようなコードを見つけることができませんでした。
  • 下記のコードでパターンがヒットしない場合で苦慮しています。REGEXMATCHはGoogleスプレッドシートのREGEXMATCH関数と同等の機能です。
回答を見る
  • ベストアンサー

VBAで時間を正規表現するパターン

VBAで時間を正規表現するパターンを教えて下さい。 セル中の文字列に混在する  時間の形式に統一性がありません。 考えられる形式は、以下のパターンです。 1:05:12 01:05:12 00:05:12 00:5:12 0:05:05 0:5:5 0:55:12 55:12 (mm:ss) 05:12 (mm:ss) 5:12 (mm:ss) 5:07 (mm:ss) 5:7 (mm:ss) ---------------------- ネットで探しても上記パターンを網羅するような  コードを探しきれませんでした。 下記のコードでパターンがヒットしない場合あり苦慮しています。 (REGEXMATCHは、セルフ関数で   Google スプレッドシートの REGEXMATCH 関数と同等の機能です。) For i = 1 To LastNo If REGEXMATCH(Ws2.Cells(i, "A"), "\d{1,2}(:\d{1,2}){1,2}") Then Ws1.Cells(i, "A") = Ws2.Cells(i, "A") '条件がTrueの場合 Else Ws1.Cells(i, "A") = "" End If Next

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

  • ベストアンサー
  • kkkkkm
  • ベストアンサー率65% (1617/2456)
回答No.5

"\d{1,2}(:\d{1,2}|:\d{1,2}){1,2}" にすれば「:」は半角全角どちらでも対応になり mMatches.Item(0).Value の値は元の半角全角が維持されます。

NuboChan
質問者

補足

kkkkkmさん、何度もアドバイスありがとうございます。 せっかくなので  半角化のコードを付加してみました。 -------------- '処理対象を半角にコンバート(対策 / [:]が全角の場合) 'For i = 1 To LastNo ' Ws2.Cells(i, "B") = StrConv(Ws2.Cells(i, "A"), vbNarrow) 'Next ---------------- 全角のカタカナが半角になるのが欠点なので  (全角の漢字及び全角のひらがなは、全角のまま) なので パターン1  mPattern = "\d{1,2}:\d{1,2}:\d{1,2}|\d{1,2}:\d{1,2}" から パターン2  mPattern = "\d{1,2}(:\d{1,2}|:\d{1,2}){1,2}" '「:」が半角全角どちらでも対応 に変更してみましたが  REGEXMATCH関数が機能しません。    (パターン1では上手く機能してセルの書き出しができていますが      パターン2では、セルの書き出しができていません。) 原因は何でしょうか ? 以下は、現在試用中のコードです。 (「処理対象を半角にコンバート(対策 / [:]が全角の場合)」の   コードは、コメントアウトして利用しなくしています。) --------------------------------------- 'Checkシート初期化 Ws1.Range("A1:B300").Clear '処理対象を半角にコンバート(対策 / [:]が全角の場合) 'For i = 1 To LastNo ' Ws2.Cells(i, "B") = StrConv(Ws2.Cells(i, "A"), vbNarrow) 'Next 'MOTOシートに時間相当の記載が有る場合のみ別シート(Checkシート)に書き出す 'mPattern -> 時間相当/正規表現 'mPattern = "[0-9][0-9]:[0-5][0-9]:[0-5][0-9]|" & _ "[0-9]:[0-5][0-9]:[0-5][0-9]|" & _ "[0-9]:[0-9]:[0-5][0-9]|" & _ "[0-9]:[0-9]:[0-9]|" & _ "[0-9]:[0-5][0-9]|" & _ "[0-9]:[0-9]" '最も長いが分かりやすい 'mPattern = "\d{1,2}(:\d{1,2}){1,2}" 'S1299792さん紹介 'mPattern = "\d{1,2}:\d{1,2}:\d{1,2}|\d{1,2}:\d{1,2}" mPattern = "\d{1,2}(:\d{1,2}|:\d{1,2}){1,2}" '「:」が半角全角どちらでも対応 Set Reg = CreateObject("VBScript.RegExp") Reg.Pattern = mPattern For i = 1 To LastNo If REGEXMATCH(Ws2.Cells(i, "B"), mPattern) Then Ws1.Cells(i, "A") = Ws2.Cells(i, "B") '条件がTrueの場合 Else Ws1.Cells(i, "A") = "" End If Next ' Excel で Google スプレッドシートの REGEXMATCH 関数相当を使う Public Function REGEXMATCH(str As String, pat As String) As Boolean Dim Reg As Object Set Reg = CreateObject("VBScript.RegExp") With Reg .Pattern = pat .IgnoreCase = False .Global = True End With REGEXMATCH = Reg.Test(str) End Function

その他の回答 (7)

  • kkkkkm
  • ベストアンサー率65% (1617/2456)
回答No.8

>   変更前は >     CHECKシートのA25が「空白」だったのが いつのコードの話をしているのか分かりませんが Trueの場合に Ws1.Cells(i, "A") = Ws2.Cells(i, "A") で空白になるとは思えません。 時間や日付だけのデータはシリアル値なのでそのまま代入すると数値で表示されます。 表示形式を適切なものにすれば時間として表示されます。 検索時のデータをvalueで渡すと生のままのデータが渡されますのでText(見た目)で渡しています。

NuboChan
質問者

お礼

>Ws1.Cells(i, "A") = Ws2.Cells(i, "A") >で空白になるとは思えません。 私がセル操作中にクリアーにしてしまったのかもしれません。 考えられそうなDATAで処理しようとすると  どうしても無理が出て、  結局、最終的に結果を肉眼で確認して   必要ないゴミを削除する作業が多くなりそうです。 あまり欲張らず   コードは、ここで完成としたいと思います。 今回もお付き合い願い感謝します。

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

> Ws1.Cells(n, "B").Text = Ws1.Cells(i, "A").Value データの取得は.Textでできますが、セットは.Textではできませんから Ws1.Cells(n, "B").Value = Ws1.Cells(i, "A").Text に変更してみてください。

NuboChan
質問者

補足

>Ws1.Cells(n, "B").Value = Ws1.Cells(i, "A").Text >に変更してみてください。 変更してみましたが、   上手く処理できていないようです。 (なぜだか?   変更前は     CHECKシートのA25が「空白」だったのが     今回は、「0.003645833」と表示されています。) 添付画像 https://imgur.com/P8KzwW6

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

>  mPattern = "\d{1,2}(:\d{1,2}|:\d{1,2}){1,2}" '「:」が半角全角どちらでも対応 > に変更してみましたが >  REGEXMATCH関数が機能しません。 質問にあるデータでは機能しました(一部カタカナも入れて)データの違いかもですが。 メインにある Set Reg = CreateObject("VBScript.RegExp") Reg.Pattern = mPattern は不要ですね。 > 'For i = 1 To LastNo > ' Ws2.Cells(i, "B") = StrConv(Ws2.Cells(i, "A"), vbNarrow) > 'Next こちらではなく検索するデータの方です。 REGEXMATCH = Reg.Test(StrConv(str, vbNarrow)) あと、単純な時間だけのデータ(02:15:10だけ)がある場合に条件はFalseになりますので、その可能性がある場合 If REGEXMATCH(Ws2.Cells(i, "B").Text, mPattern) Then としておくといいと思います。

NuboChan
質問者

お礼

>質問にあるデータでは機能しました すいません。  kkkkkmさんから指摘されて、コードを見直して  ミスが発覚したのでコードを修正しました。   (単純な時間だけのデータが有る場合のコードへ修正済み)  下記が現在の(修正後の)コードです。    (マクロを起動後の画像を添付します。) https://imgur.com/cz1Uytn 全角のカタカナが半角になるのが欠点も無く  これで完成と思われましたが  なんと、   「A列を対象にB列に空白のセルをとばして(詰めて)転記する」  コードを実施すると復活しました。 Ws1.Cells(n, "B")= Ws1.Cells(i, "A") を以下のように変えましたが  Ws1.Cells(n, "B").Text = Ws1.Cells(i, "A").Value RangeクラスのTextプロパティを設定できません (1004エラー) が出ます。 最終的には、不必要なセルは肉眼で確認して  削除することになるのでそれほど大変ではなさそうですが  エラーが出なくなる方法はありますか ? -------------------------------------------------------- Option Explicit Sub Check_HHMMSS() Dim Ws1 As Worksheet Dim Ws2 As Worksheet Dim LastNo As Single Dim hhmmss As Object Dim i As Single Dim n As Single Dim Reg As Object Dim mMatches As Object Dim mPattern As String Set Ws1 = Worksheets("Check") Set Ws2 = Worksheets("MOTO") LastNo = Ws2.Cells(Rows.Count, "A").End(xlUp).Row MsgBox "MOTOシートのA列にチェックする元になるLISTは存在しますか ?", 1 + 32, "Form_hhmmss" If LastNo = 0 Then MsgBox "元リストがA列に無いので処理を中止します" Exit Sub Else '処理 End If 'Checkシート初期化 Ws1.Range("A1:B300").Clear 'MOTOシートに時間相当の記載が有る場合のみ別シート(Checkシート)に書き出す 'mPattern -> 時間相当/正規表現 mPattern = "\d{1,2}(:\d{1,2}|:\d{1,2}){1,2}" '「:」が半角全角どちらでも対応 For i = 1 To LastNo If REGEXMATCH(Ws2.Cells(i, "A").Text, mPattern) Then Ws1.Cells(i, "A") = Ws2.Cells(i, "A") '条件がTrueの場合 Else Ws1.Cells(i, "A") = "" End If Next 'A列を対象にB列に空白のセルをとばして(詰めて)転記する n = 1 For i = 1 To LastNo If Ws1.Cells(i, "A") <> "" Then Ws1.Cells(n, "B").Text = Ws1.Cells(i, "A").Value n = n + 1 End If Next Set Ws1 = Nothing Set Ws2 = Nothing End Sub ' Excel で Google スプレッドシートの REGEXMATCH 関数相当を使う Public Function REGEXMATCH(str As String, pat As String) As Boolean Dim Reg As Object Set Reg = CreateObject("VBScript.RegExp") With Reg .Pattern = pat .IgnoreCase = False .Global = True End With REGEXMATCH = Reg.Test(str) End Function

  • kkkkkm
  • ベストアンサー率65% (1617/2456)
回答No.4

> 必要なら「:」の全角を半角に修正するコードを追加する予定です。 Set mMatches = Reg.Execute(StrConv(Cells(i, "A").Text, vbNarrow)) の StrConv(Cells(i, "A").Text, vbNarrow) で、セルの値を半角にして検査してますから「:」全角も検査結果は正しく出てると思います。 結果のmMatches.Item(0).Valueは半角にしたままです。

  • kkkkkm
  • ベストアンサー率65% (1617/2456)
回答No.3

"\d{1,2}(:\d{1,2}){1,2}" は質問に書いてあったパターンです。 それで駄目だと記載があったので、駄目なんだなぁと思って全てのパターンを考えて で、あとから試しにやってみたらできる感じだったので追加回答しました。 いまいちよくわかりませんが \dは数値で0から9 {1,2}1文字から2文字 ()はグループ みたいですから、 「:」の前後1文字から2文字が数値で ()が繰り返し対応「:」2回対応、()で括るとそうなるのでしょう。 ()の用法がよくわかりませんから、これを見るまでは "\d{1,2}:\d{1,2}:\d{1,2}|\d{1,2}:\d{1,2}" としたと思います。

NuboChan
質問者

補足

>"\d{1,2}(:\d{1,2}){1,2}" >は質問に書いてあったパターンです。 失礼しました。 "\d{1,2}(:\d{1,2}){1,2}" は、  前回、「VBA - 区切り文字前後で抜き出す」で質問したとき  その時は気づいたいなかったのですが  kkkkkmさん以外に「S1299792」さんから回答を頂いていて  解決後に回答が有った事に気が付いて  便利な正規表現を紹介いただきました。 (S1299792さん、気が付かずに大変失礼しました。)  ダメな場合が有ると言ったのは    「:」が全角の場合、上手く処理できないようです。     (:が半角文字の場合はOK) たまたま今回サンプルに使った中に   全角の「:」が無かったので上手く処理できました。 自分で質問に挙げておいて   すっかり "\d{1,2}(:\d{1,2}){1,2}" の存在を忘れていました。 --------------------------- kkkkkmさんでも難解な正規表現なので 初心者の私は、どこで区切って考えたら良いか?    さっぱり分からないのが現状です。 ---------------------------------- >\d{1,2}:\d{1,2}:\d{1,2}|\d{1,2}:\d{1,2}  こちらも上手く処理できています。 (「:」が全角文字の場合を除く)     必要なら「:」の全角を半角に修正するコードを追加する予定です。   

  • kkkkkm
  • ベストアンサー率65% (1617/2456)
回答No.2

No1のmPatternを mPattern = "\d{1,2}(:\d{1,2}){1,2}" にしてもいけそうな感じですが

NuboChan
質問者

お礼

違うパターンを追加で紹介いただきありがとうございます。 >mPattern = "\d{1,2}(:\d{1,2}){1,2}" こちらでも上手く処理できました。 \d{1,2}(:\d{1,2}){1,2} は、まるで私には呪文です。 これを読み解くとどのようになるのか?  解説いただければ嬉しいです。

  • kkkkkm
  • ベストアンサー率65% (1617/2456)
回答No.1

強引に全てのパターンをORで繋ぐとか (書式は最初標準にしておいて) Sub Test() Dim Reg As Object Dim mMatches As Object Dim mPattern As String mPattern = "[0-9][0-9]:[0-5][0-9]:[0-5][0-9]|" & _ "[0-9]:[0-5][0-9]:[0-5][0-9]|" & _ "[0-9]:[0-9]:[0-5][0-9]|" & _ "[0-9]:[0-9]:[0-9]|" & _ "[0-9]:[0-5][0-9]|" & _ "[0-9]:[0-9]" Set Reg = CreateObject("VBScript.RegExp") Reg.Pattern = mPattern For i = 1 To 50 Set mMatches = Reg.Execute(StrConv(Cells(i, "A").Text, vbNarrow)) If mMatches.Count > 0 Then ' If IsDate(mMatches.Item(0).Value) Then Cells(i, "C").Value = mMatches.Item(0).Value ' End If End If Next End Sub

NuboChan
質問者

お礼

kkkkkmさん、回答感謝します。 正規表現(mPattern)で上手く処理できました。 時間相当パターン(正規表現)は、  使えると非常に便利なので利用したいのですが  初心者の私にはなじみが少なく  現状、非常に難易度が高い存在です。    実際のサンプルを利用してコードを使いやすく改造中です。  (過去、しばらくするとマクロの利用方法を忘れてしまう事が   頻発したのでコード中にコメントを増やしたり   マクロの進行に合わせてMSGBOXで進行の補助的メッセージを   表示するようにしています。)  今回も無事に解決しました。    

関連するQ&A

  • (VBA)FORMATを変換して書き出したい

    以下のようなテキストファイルを CHAPTER01=0:00:00.000 CHAPTER01NAME=test_001 CHAPTER02=0:04:02.719 CHAPTER02NAME=test_456 CHAPTER03=0:08:33.859 CHAPTER03NAME=test_741 下記のようなフォーマットにEXCELのVBAを利用して変更してテキストファイルで書き出したい 最初のモデルになるようなマクロコードを教えてください。 1 00:00:00,000 --> 00:00:10.000 test_001 2 00:04:02,719 --> 00:04:12.719 test_456 3 00:08:33,859 --> 00:08:43.859 test_456 このように、番号、開始時間と終了時間、テキストの3つの要素があります。 時間は時:分:秒,ミリ秒の形式で表されます。 各要素は空白行で区切られます。 終了時間=開始時間+10秒(00:00:10.000) ’---------------------------- 一応、何とか自前でコードは完成しましたが 運用上は問題なのですが算数的にはおこしな事になっています。 以下でDtime(10秒)を加算していますが ws2.Cells(i, "B") = DateAdd("s", Dtime, ws2.Cells(i, "A")) ws2.Cells(i, "A") が 0:04:02.719 だとすると 0:04:12.719 になるはずが 実際は、ws2.Cells(i, "B") は  0:04:13.000 と小数点以下がゼロになっています。 訂正を及びコードに関してアドバイスあればお願いします。 Option Explicit Sub test() Dim ws1 As Worksheet, ws2 As Worksheet Dim ls As Long, i As Long Set ws1 = Worksheets("DATA") Set ws2 = Worksheets("Convert") ls = ws1.Cells(Rows.Count, "A").End(xlUp).Row Dim txt As String Dim Dtime As String ws2.Cells.Clear ws2.Columns("A").NumberFormatLocal = "h:mm:ss.000" ws2.Columns("B").NumberFormatLocal = "h:mm:ss.000" For i = 1 To ls Step 2 '開始時間 txt = ws1.Cells(i, "A").Value ws2.Cells(i, "A") = Mid(txt, InStr(txt, "=") + 1) '表示時間指定 (任意) Dtime = 10 '終了時間 ws2.Cells(i, "B") = DateAdd("s", Dtime, ws2.Cells(i, "A")) '開始時間に10秒を加算 '時間部(開始 --> 終了) ws2.Cells(i, "C") = ws2.Cells(i, "A").Text & " --> " & ws2.Cells(i, "B").Text 'Title txt = ws1.Cells(i + 1, "A").Value ws2.Cells(i + 1, "C") = Mid(txt, InStr(txt, "=") + 1) Next 'Plane Text 保存 ----------------- Dim R_data As Integer '行番号 R_data = 1 Open "C:\Users\ABC\Desktop\Plane_text.txt" For Output As #1 Do While ws2.Cells(R_data, "C") <> "" Print #1, ws2.Cells(R_data, "C") If R_data Mod 2 = 0 Then '2の倍数のとき Print #1, "" '空白行を出力 End If R_data = R_data + 1 Loop Close #1 End Sub ’---------------------------------

  • (VBA) FOR文の修正をお願いします。

    基本的な事でうまく処理できません。 下記コードで シート(DATA)の内容を シート(Chapter)に順番(FOR文)に書き出したいのですが  コードの修正をお願いします。 添付画像で説明すると  ①の内容を  ②のように書き換えたいのですが  実際の現在のコードでは③のようになってしまいます。 FOR文の変数(I)とSTEPの値が間違っているのですが  基本的なことですいません。 ------------------------------------------------------------- Set WS1 = Worksheets("DATA") With Worksheets("Chapter") For I = 1 To EndLow - 2 Step 2 .Cells(I, "A") = "CHAPTER" & WS1.Cells(I + 2, "H") & "=" & Format(WS1.Cells(I + 2, "E").Value, "h:mm:ss") .Cells(I + 1, "A") = "CHAPTERNAME=" & WS1.Cells(I + 2, "G") Next End With

  • VBA 検索するSheetの位置の変更

    現在、グループの数だけユーザー名の合計数をSheet2に抽出するという 事をやっているのですが....... コードの方は下記になります Sub Sample3() Dim i As Long, j As Long, k As Long, lastRow As Long, lastCol As Long Dim wS2 As Worksheet, wS3 As Worksheet Set wS2 = Worksheets("Sheet1") Set wS3 = Worksheets("Sheet2") Application.ScreenUpdating = False If wS2.Range("Y1") = "" Then wS2.Range("Y1") = "ダミー" End If With Worksheets("Sheet1") If .Range("A4") = "" Then .Range("A4") = "ダミー" End If lastRow = .Cells(Rows.Count, "B").End(xlUp).Row Range(.Cells(5, "B"), .Cells(lastRow, "B")).AdvancedFilter Action:=xlFilterCopy, copytorange:=wS3.Range("A1"), unique:=True '★ For i = 2 To wS3.Cells(Rows.Count, "A").End(xlUp).Row wS2.Cells(7, (i - 2) * 8 + 3) = wS3.Cells(i, "A") .Range("A4").AutoFilter field:=2, Criteria1:=wS3.Cells(i, "A") Range(.Cells(5, "AA"), .Cells(lastRow, "AA")).SpecialCells(xlCellTypeVisible).Copy wS2.Cells(7, (i - 2) * 8 + 2) For k = wS2.Cells(Rows.Count, (i - 2) * 8 + 2).End(xlUp).Row To 7 Step -1 wS2.Cells(k, (i - 2) * 8 + 3) = WorksheetFunction.CountIfs(.Range("AA:AA"), wS2.Cells(k, (i - 2) * 8 + 2), .Range("B:B"), _ wS2.Cells(7, (i - 2) * 8 + 3)) If WorksheetFunction.CountIf(wS2.Columns((i - 2) * 8 + 2), wS2.Cells(k, (i - 2) * 8 + 2)) > 1 Then wS2.Cells(k, (i - 2) * 8 + 2).Resize(, 2).Delete shift:=xlUp End If Next k Next i wS2.Range("B1").CurrentRegion.Borders.LineStyle = xlContinuous wS2.Cells.Replace what:="ダミー", replacement:="", lookat:=xlWhole .Cells.Replace what:="ダミー", replacement:="", lookat:=xlWhole wS3.Cells.Clear .AutoFilterMode = False End With Application.ScreenUpdating = True End Sub このコードで検索をかけるSheet1のセルBの文字をセルCに移動して検索かけたいという事なのですが、下記の用なコードでBをCに変更してみた結果エラーが発生してしまいます。 lastRow = .Cells(Rows.Count, "C").End(xlUp).Row Range(.Cells(5, "C"), .Cells(lastRow, "C")).AdvancedFilter Action:=xlFilterCopy, copytorange:=wS3.Range("A1"), unique:=True '★ For i = 2 To wS3.Cells(Rows.Count, "A").End(xlUp).Row wS2.Cells(7, (i - 2) * 8 + 3) = wS3.Cells(i, "A") .Range("A4").AutoFilter field:=2, Criteria1:=wS3.Cells(i, "A") Range(.Cells(5, "AA"), .Cells(lastRow, "AA")).SpecialCells(xlCellTypeVisible).Copy wS2.Cells(7, (i - 2) * 8 + 2) For k = wS2.Cells(Rows.Count, (i - 2) * 8 + 2).End(xlUp).Row To 7 Step -1 wS2.Cells(k, (i - 2) * 8 + 3) = WorksheetFunction.CountIfs(.Range("AA:AA"), wS2.Cells(k, (i - 2) * 8 + 2), .Range("C:C"), _ どなたかご教授の方お願い致します。

  • VBA 高速化

    以下のコードを改良して早く処理できるようにしたいです。素因数分解をして、素因数の数を数えるプログラムです。 Sub 素因数を数える() Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Dim I As Long, j As Long, cnt As Long, wS As Worksheet, k As Long, Set wS = Worksheets("Sheet2") k = Worksheets("Sheet1").Range("A100010").End(xlUp).Row - 1 For dd = 3 To k Call aaa(Range("A" & dd)) Next dd Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub Private Sub aaa(ByVal Target As Range) Set wS = Worksheets("Sheet2") If Intersect(Target, Range("A:A")) Is Nothing Or Target.Count > 1 Then Exit Sub With Target If Not IsNumeric(.Value) Then Exit Sub If .Value Mod 1 = 0 Then Range("D1") = .Value For I = 1 To wS.Cells(Rows.Count, "A").End(xlUp).Row Do While Cells(Rows.Count, "D").End(xlUp) Mod wS.Cells(I, 1) = 0 cnt = cnt + 1 Cells(Rows.Count, "D").End(xlUp).Offset(1) = Cells(Rows.Count, "D").End(xlUp) / wS.Cells(I, 1) Loop If Cells(Rows.Count, "D").End(xlUp) = 1 Then Exit For Next I End If .Offset(, 1) = cnt End With Range("D:D").Clear End Sub 以前教えていただいたコードを使って書きました。 どういう状況で使っているかといいますと、シート1のA列に自然数を2から順番に並べ、シート2のA列に素数を並べておき、プログラムを実行すると、B列に素数の数が表示されるという具合です。 大変役に立っていたのですが、10萬ほどのデータを扱おうとすると、自分のコンピュータでは時間がかかりすぎます。そこでコードを改良して高速化をしたいのです。 いま考えられる改良点は、 1、D列を使って行っている処理をメモリで行うようにして、セルへのアクセスを省けないか 2、aaaの5行目の、"wS.Cells(Rows.Count, "A").End(xlUp).Row"この処理を簡単な変数の処理で代用できないか ということです。他にも高速化できる方法があれば教えてください。 よろしくお願いします。

  • vbaで正規表現

    正規表現のコードなんですが、 上手く動きません。 何故でしょうか… Sub Test() Dim reg As Object Dim ans As Object Dim c As Range         Set reg = CreateObject("VBScript.RegExp")     For Each c In Range("A1", Range("A" & Rows.Count).End(xlUp))             With reg             .Pattern = "^【[(1)-(20)](\d*/\d*)"             Set ans = .Execute(c.Value)         End With                 If ans > 0 Then             If Len(ans(0).submatches(0)) > 0 Then                             Debug.Print c.Address & "|" & ans(0).submatches(0)                             End If         End If             Next     End Sub

  • 【VBA】【正規表現】

    23歳OLです。 VBAと正規表現についての質問です。 ▼やりたいこと ================================================ 1 | 0 |1234567890 | 2014-2-22 22:22:22.06+09 という数列から 1234567890 という数字のみを抜き出したいです。 正確には2本目の|と3本目の|の間に入っている様々な数字です。 ※桁数が固定されていません。 ================================================ ▼実際書いたコード ================================================ Sub Sample2() Dim RE, strPattern As String, i As Long, msg As String, reMatch Set RE = CreateObject("VBScript.RegExp") strPattern = "☆この部分☆" With RE .Pattern = strPattern .IgnoreCase = True .Global = True For i = 1 To 10 Set reMatch = .Execute(Cells(i, 1)) If reMatch.Count > 0 Then msg = msg & reMatch(0).Value & vbCrLf End If Next i End With MsgBox msg Set reMatch = Nothing Set RE = Nothing End Sub ================================================ ☆この部分に☆に何を入れればよいでしょう? ご指導よろしくおねがいします。

  • Excel VBA 連番印刷

    昨日以下の質問をさせていただいた者です。 http://okwave.jp/qa/q8349562.html こちらで教えていただいた以下のコードに、 J2のセルに連番を振るコードを付け足したいと思い、 同じくこちらのサイトの過去の履歴にあった以下コードを参考にとやってみているのですが、 Next で指定された変数の参照が無効です。と言われてしまいます… 印刷部数の指定はいらず、sheet印刷のJ2セルに1から始まる連番を振りたいのです。 どのように修正をしたらいいのかご教示願います。 Sub Sample4() Dim i As Long, endRow1 As Long, endRow2 As Long, myArea1 As Range, myArea2 As Range Dim wS1 As Worksheet, wS2 As Worksheet, wS3 As Worksheet Set wS1 = Worksheets("DB") Set wS2 = Worksheets("印刷") Set wS3 = Worksheets("Sheet3") endRow1 = wS1.Cells(Rows.Count, "A").End(xlUp).Row Range(wS1.Cells(1, "A"), wS1.Cells(endRow1, "A")).AdvancedFilter Action:=xlFilterInPlace, unique:=True wS1.Range("A:A").Copy wS3.Range("A1") wS1.ShowAllData For i = 2 To wS3.Cells(Rows.Count, "A").End(xlUp).Row endRow2 = wS2.Cells(Rows.Count, "B").End(xlUp).Row If endRow2 > 9 Then Range(wS2.Cells(10, "B"), wS2.Cells(endRow2, "H")).ClearContents Range(wS2.Cells(10, "J"), wS2.Cells(endRow2, "J")).ClearContents End If wS1.Range("A1").AutoFilter field:=1, Criteria1:=wS3.Cells(i, "A") wS2.Range("B6") = wS3.Cells(i, "A") Set myArea1 = Range(wS1.Cells(2, "B"), wS1.Cells(endRow1, "H")).SpecialCells(xlCellTypeVisible) Set myArea2 = Range(wS1.Cells(2, "I"), wS1.Cells(endRow1, "I")).SpecialCells(xlCellTypeVisible) myArea1.Copy wS2.Activate ActiveSheet.Range("B10").Select Selection.PasteSpecial Paste:=xlPasteValues myArea2.Copy wS2.Activate ActiveSheet.Range("J10").Select Selection.PasteSpecial Paste:=xlPasteValues endRow2 = wS2.Cells(Rows.Count, "B").End(xlUp).Row 'Range(wS2.Cells(1, "A"), wS2.Cells(endRow2, "J")).PrintOut Next i wS1.AutoFilterMode = False wS3.Cells.Clear End Sub 連番印刷のコード Sub NumberPrint() Dim idx As Integer Dim res  res = Application.InputBox("印刷部数を入力してください", Type:=1)  If res > 0 Then   For idx = 1 To res    Range("AW3").Value = idx    ActiveSheet.PrintOut   Next idx  End If End Sub

  • VBA 時間の抜き出しが上手く処理できない

    時間の抜き出しをするのに下記のコードを候補に挙げましたが、 「'コロンが2個の場合 (時:分:秒)」の場合は上手く処理できますが 「'コロンが1個の場合 (分:秒)」の数値が上手く処理できません。 ’----------------------------------------------------------------------- Option Explicit Sub コロンの数を数える() Dim i As Long, cnt As Long, n As Variant For i = 2 To Cells(Rows.Count, "A").End(xlUp).Row cnt = 0 '←cntをリセット Do n = InStr(n + 1, Cells(i, "A"), ":") If n = 0 Then Exit Do Else cnt = cnt + 1 End If Loop If cnt < 1 Then MsgBox "[:]がありません。" '←cntが1未満のときにメッセージを発出します。 End Else Cells(i, "B").Value = cnt End If Next End Sub Sub 時間抜き出し() Dim i As Long, cnt As Long Dim n As Single For i = 2 To Cells(Rows.Count, "A").End(xlUp).Row n = InStr(n + 1, Cells(i, "A"), ":") 'コロン「:」の位置を特定する If Cells(i, "B") = 1 Then 'コロンが1個の場合 (分:秒) Cells(i, "C").NumberFormatLocal = "h:mm:ss" If Mid(Cells(i, "A"), n - 2, 1) = " " Or Mid(Cells(i, "A"), n - 2, 1) = "(" Then '10分以下の場合 Cells(i, "C") = Mid(Cells(i, "A"), n - 1, 4) Cells(i, "C") = "0:" & Cells(i, "C") Else '10分以上 Cells(i, "C") = Mid(Cells(i, "A"), n - 2, 5) Cells(i, "C") = "0:" & Cells(i, "C") End If Else 'コロンが2個の場合 (時:分:秒) Cells(i, "C").NumberFormatLocal = "h:mm:ss" Cells(i, "c") = Mid(Cells(i, "A"), n - 1, 7) End If n = 0 Next End Sub

  • 【至急助けて下さい!!】VBAでのIF関数挿入

    VBA初心者です。上級者の方助けてください。 VBAで入力セルを消去後、IF関数をN列に挿入したいです。 挿入したいIF関数のところが解決できればあとの記述はなんとかなります。 ■挿入したいIF関数 =IF(M4=$Y$5,$Z$9,IF(M4=$Y$6,$Z$9,IF(M4=$Y$7,$Z$9,IF(M4=$Y$8,$Z$6,IF(M4=$Y$9,$Z$10,IF(M4=$Y$10,$Z$9,IF(M4=$Y$14,$Z$7,IF(M4=$Y$15,$Z$8,"")))))))) 他関数は下記構文でうまくいくのですが、 IF関数はどのように記述したらよろしいでしょうか。 ■他 ws.Cells(i, jig_col).Value = "=VLOOKUP(F" & i & ",Sheet1!$A$2:$C$358,2,0)" ■現在の記述 Dim ws As Worksheet Dim endrow As Long Dim endcol As Long Dim you_col As Integer Dim gak_col As Integer Dim jig_col As Integer Dim bc_col As Integer Dim chg_col As Integer Dim i As Long '確認メッセージを表示し、「NO」の場合は処理を行わない If MsgBox("入力されている内容をクリアします。よろしいですか?", vbYesNo) = vbNo Then Exit Sub End If '画面の更新を行わない Application.ScreenUpdating = False Set ws = ThisWorkbook.Sheets("シンフォームイレギュラー運用状況") '呼び出し元シートの最終行、最終列を取得する endrow = ws.Cells(ws.Rows.Count, 6).End(xlUp).Row endcol = ws.Cells.Find(What:="変更フラグ", LookIn:=xlValues, LookAt:=xlWhole).Column - 2 If endrow < 4 Then Exit Sub ws.Range(ws.Cells(4, 1), ws.Cells(endrow, endcol)).ClearContents you_col = ws.Cells.Find(What:="曜日", LookIn:=xlValues, LookAt:=xlWhole).Column gak_col = ws.Cells.Find(What:="学年", LookIn:=xlValues, LookAt:=xlWhole).Column jig_col = ws.Cells.Find(What:="事業所", LookIn:=xlValues, LookAt:=xlWhole).Column 'bc_col = endcol - 1 'chg_col = endcol For i = 4 To endrow ws.Cells(i, you_col).Value = "=B" & i ws.Cells(i, gak_col).Value = "=VLOOKUP(F" & i & ",Sheet1!$A$2:$C$358,3,0)" ws.Cells(i, jig_col).Value = "=VLOOKUP(F" & i & ",Sheet1!$A$2:$C$358,2,0)" 'ws.Cells(i, bc_col).Value = "=IFERROR(MID(H" & i & ",LEN(H" & i & ")-1,1), "")" 'ws.Cells(i, chg_col).Value = 0 ws.Range("W" & i).Value = 0 Next '画面の更新を行う Application.ScreenUpdating = True End Sub

  • VBA 請求データ一覧からの複数の処理

    先週 kkkkkmさんに質問をさせて頂きまして、 いろいろご指導を頂いたものです。 続編の様な形になってしまいますが、 抽出するデータの環境設定を変更致しました。 ご質問させて頂く内容は前回とほとんど変更がないのですが、 あらためて下記に記載させて頂きます。 <Worksheet1のデータ> J列~AM列までが課税金額 「J,K,L」「M,N,O」・・・「AK,AL,AM」と3列1組(コード・費目・金額) 1組の行もあれば、複数組の行もあり。 AN列~BB列までが非課税金額 課税金額と同じく3列1組 1組の行もあれば、複数組の行もあり。 「BC」=消費税、「BD」=合計金額 ※AN列の前に不規則な空白セルあり   BC列の前に不規則な空白セルあり 文章で上手く説明出来ているか自信がありませんので、 エクスポートした元データ Worksheet1と、 vbaを用いて作成した Worksheet3 をご参考に添付致します。 Worksheet1の2行目がWorksheet3の2行目に対応しています。 3行目、4行目も同様です。 不規則な空白が原因でしょうか・・・。 M列、O列は問題ないのですが、 金額が合わなかったり、N列に金額を引いてこないのです。 実行しているコードは下記になります。 Dim i As Long, j As Long, k As Long Dim Ws1 As Worksheet, Ws2 As Worksheet, Ws3 As Worksheet Dim mTotal(4) As Long Dim LastRow As Long Dim List(4) As Variant Set Ws1 = Sheets("Sheet1") Set Ws2 = Sheets("Sheet2") Set Ws3 = Sheets("請求書ひな形") List(1) = Ws2.Range(Ws2.Cells(1, "A"), Ws2.Cells(Rows.Count, "A").End(xlUp)).Value List(2) = Ws2.Range(Ws2.Cells(1, "B"), Ws2.Cells(Rows.Count, "B").End(xlUp)).Value List(3) = Ws2.Range(Ws2.Cells(1, "C"), Ws2.Cells(Rows.Count, "C").End(xlUp)).Value List(4) = Ws2.Range(Ws2.Cells(1, "D"), Ws2.Cells(Rows.Count, "D").End(xlUp)).Value LastRow = UBound(List(1)) For i = 2 To 4 If LastRow < UBound(List(i)) Then LastRow = UBound(List(i)) End If Next For i = 2 To Ws1.Cells(Rows.Count, "J").End(xlUp).Row mTotal(1) = 0 mTotal(2) = 0 mTotal(3) = 0 mTotal(4) = 0 For j = Columns("J").Column To Columns("BB").Column Step 3 For k = 2 To LastRow If UBound(List(1)) >= k Then If Ws1.Cells(i, j).Value = List(1)(k, 1) Then mTotal(1) = mTotal(1) + Ws1.Cells(i, j).Offset(0, 2).Value Exit For End If End If If UBound(List(2)) >= k Then If Ws1.Cells(i, j).Value = List(2)(k, 1) Then mTotal(2) = mTotal(2) + Ws1.Cells(i, j).Offset(0, 2).Value Exit For End If End If If UBound(List(3)) >= k Then If Ws1.Cells(i, j).Value = List(3)(k, 1) Then mTotal(3) = mTotal(3) + Ws1.Cells(i, j).Offset(0, 2).Value Exit For End If End If If UBound(List(4)) >= k Then If Ws1.Cells(i, j).Value = List(4)(k, 1) Then mTotal(4) = mTotal(4) + Ws1.Cells(i, j).Offset(0, 2).Value Exit For End If End If Next Next Ws3.Cells(i, "J").Value = mTotal(1) Ws3.Cells(i, "K").Value = mTotal(2) Ws3.Cells(i, "L").Value = mTotal(3) Ws3.Cells(i, "N").Value = mTotal(4) Ws3.Cells(i, "M").Value = Ws1.Cells(i, "BC").Value Ws3.Cells(i, "O").Value = Ws1.Cells(i, "BD").Value Next Set Ws1 = Nothing Set Ws2 = Nothing Set Ws3 = Nothing End Sub 本当に何度も申し訳ございません。 お時間がある時に見て頂けると有り難いです。 どうぞ宜しくお願い致します。

専門家に質問してみよう