Excel VBAで英字と数字の間のハイフンのクリア方法について

このQ&Aのポイント
  • ExcelのVBAコードを使用して、英字と数字の間のハイフンをクリアする方法について教えてください。
  • 現在、B4:CH4の範囲で半角英数字の小文字を入力すると自動で大文字に変換され、ハイフンを入力すると文字がクリアされるVBAコードがあります。ただし、現在のコードでは英字と数字の間のハイフンもクリアされてしまいます。数字と数字の間のハイフンの場合はクリアしないようにするためには、どのようなコードを追加すれば良いでしょうか?
  • 例えば、「GRE-879」の場合はハイフンをクリア対象とし、「GRE868-76」の場合はハイフンをクリアしないようにしたいです。このような条件を満たすVBAコードの作成方法を教えてください。
回答を見る
  • ベストアンサー

数字と数字のー(ハイフン)は消去しないVBA

Private Sub Worksheet_Change(ByVal Target As Range) Dim myAsc As Integer, InSP As Integer, myFlag As Integer Dim myStr As String If Intersect(Target, Range("B4:CH4")) Is Nothing Then Exit Sub If Application.CountBlank(Target) > 0 Then Exit Sub Application.EnableEvents = False Target = StrConv(Target, vbUpperCase + vbNarrow) myStr = Target.Value InSP = 0: myFlag = 0 For i = 1 To Len(myStr) myAsc = Asc(Mid(myStr, i, 1)) If Not (myAsc >= 65 And myAsc <= 90) Then If Not (myAsc >= 48 And myAsc <= 57) Then If myAsc = 32 Then InSP = i Else MsgBox ("-(ハイフン)は使用出来ません。クリアします。" & "" & Mid(myStr, i, 1) & "") Target.Select ' Selection.ClearContents Application.EnableEvents = True Exit Sub End If ElseIf myFlag = 0 And InSP = 0 Then myFlag = i End If End If Next If myFlag <> 0 Then Target.Value = Left(myStr, myFlag - 1) & Mid(myStr, myFlag, 99) End If Application.EnableEvents = True End Sub B4:CH4の範囲で半角英数字の小文字で入力したら自動で大文字となり、-(ハイフン)を入力したら文字がクリアされるVBAがあります。 質問ですが先ほどのVBAで英字と数字の間のー(ハイフン)はクリア対象となり、数字と数字の間にー(ハイフン)の場合はクリアしないVBAはどの様にすれば良いでしょうか? ※「GRE-879」の時は消去対象となり、「GRE868-76」の時は消去しない感じです。

noname#247334
noname#247334

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

  • ベストアンサー
回答No.1

そんなに難しく考えずに、 半角ハイフン("-" コードは45)かどうかだけ見て、 両隣が「数字以外」だったら消す という具合で書いてあげれば良いかと思いますが・・ まぁ、この程度ならエラー処理は「Resume Next」で充分かと。 Private Sub Worksheet_Change(ByVal Target As Range) Dim myAsc1 As Integer, myAsc2 As Integer, myAsc3 As Integer Dim myStr As String   If Intersect(Target, Range("B4:CH4")) Is Nothing Then Exit Sub   If Len(Target.Value) = 0 Then Exit Sub   On Error Resume Next   Application.EnableEvents = False   Target = StrConv(Target, vbUpperCase + vbNarrow)   myStr = Target.Value   For i = Len(myStr) To 1 Step -1     myAsc1 = Asc(Mid(myStr, i, 1))     If myAsc1 = 45 Then       myAsc2 = Asc(Mid(myStr, i - 1, 1))       myAsc3 = Asc(Mid(myStr, i + 1, 1))       If Not (myAsc2 >= 48 And myAsc2 <= 57 And _          myAsc3 >= 48 And myAsc3 <= 57) Then         Target.Value = Left(Target.Value, i - 1) & _                Right(Target.Value, Len(Target.Value) - i)       End If     End If   Next   On Error GoTo 0   Application.EnableEvents = True End Sub とりあえず、行(列)削除と同じ要領で、文字列を後ろから見ていきます。 で、半角ハイフンが複数あると嫌なので、全桁について反復。 同じ理由からReplaceがうまくないので、LeftとRightで回りくどく。 ・・・といった感じです。 ほんとは先頭・末尾がハイフンだったらも考えようとしたんですが、 同様の考え方でいけるので(面倒だったので)割愛です。 う~ん、あまりスマートではないな(汗)

noname#247334
質問者

お礼

この度は質問に答えていただきありがとうございます。 無事に解決出来ました。

関連するQ&A

  • 2つのVBAを組み合わせる方法

    お世話になります、2つのVBAを組み合わせる方法で迷っています。 1つ目が Private Sub Worksheet_Change(ByVal Target As Range) Dim i As Long, k As Long, myNum As Long If Intersect(Target, Range("C1,B9:B39")) Is Nothing Or Target.Count > 1 Then Exit Sub Application.EnableEvents = False With Target If .Column = 3 Then myNum = WorksheetFunction.Max(Range("B9:B39")) If IsDate(.Value) Then For i = 9 To 39 If Cells(i, "A").Value = "" Then Cells(i, "B").Value = "" Else Cells(i, "B") = myNum + i - 8 End If Next i End If Else i = .Row If .Value = "" Then Range(Cells(i + 1, "B"), Cells(39, "B")).ClearContents Else For k = i + 1 To 39 If Cells(k, "A").Value = "" Then Cells(k, "B").Value = "" Else Cells(k, "B") = Cells(k - 1, "B") + 1 End If Next k End If End If End With Application.EnableEvents = True End Sub です。 2つめが Private Sub Worksheet_Change(ByVal Target As Range)  Application.EnableEvents = True If Intersect(Target, Range("R8:R38")) Is Nothing Then Exit Sub Application.EnableEvents = False Range(Cells(Target.Row, 18), Cells(39, 18)).Value = Target.Value Application.EnableEvents = True End Sub です。2つのPrivate Sub Worksheet_Change(ByVal Target As Range)イベントのVBAですが、どのようにして組み合わせれば良いのでしょうか?

  • Excel 置換? VBA

    先ほども質問したんですが、 A1に010と入力すると田中、020入力で鈴木と出来るように、 ------------------------------------------------------ Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address <> "$A$1" Then Exit Sub Select Case Target.Value Case "010": myStr = "田中" Case "020": myStr = "鈴木" Case "030": myStr = "岡田" Case "": myStr = "" Case Else: myStr = "非該当" End Select Application.EnableEvents = False On Error GoTo line Target.Value = myStr line: Application.EnableEvents = True End Sub ---------------------------------------------------- を教えていただきました! が、A2でも同じようなことを行いたいのです! VBAの知識が乏しいのでコピペでいろいろやってみたのですが、エラーで出来ませんでした…。 A1 A2 ・ ・ ・ と同じように入力できるようにするにはどのようにすればよいのでしょうか?もう一度教えて下さい。よろしくお願いします。

  • VBAについて教えてください。

    過去のQNo.457545であったのですが エクセルに20080801と入力すると 自動的に平成20年8月1日と表示されるVBAについて 下記の構文で可能ということでした。 この場合、変換がされるのは A1からA10までのセルだと思うのですが 加えてC1からC10も変換させるには どこかに入力を加えることで 可能になるでしょうか? よろしくお願いします。 QNo.457545にあった構文です。 Sheet1のコードウインドウに貼り付け ↓ Const HenkanAdr = "A1:A10" 'この範囲で機能する。変更して下さい Private Sub Worksheet_Change(ByVal Target As Excel.Range)   Dim txt As String   Application.EnableEvents = False   On Error GoTo ErrorHandler   If Target.Count = 1 Then     If Not Intersect(Target, Range(HenkanAdr)) Is Nothing Then       txt = Right("00000000" & Target.Text, 8)       txt = Left(txt, 4) & "/" & Mid(txt, 5, 2) & "/" & Right(txt, 2)       Target = Format(txt, "gggee年mm月dd日")     End If   End If   Application.EnableEvents = True   Exit Sub ErrorHandler:   Application.EnableEvents = True End Sub

  • またまた エクセルのユーザー定義で

    前回以下のようなコードを教えていただきましたが、この変換を複数列で使えるようにするにはどうしたらいいのでしょうか? D,G,N,Q,X,AA,の列に効かせたいのですが。 Private Sub worksheet_change(ByVal Target As Range) If Intersect(Target, Columns(1)) Is Nothing Or Selection.Count <> 1 Then Exit Sub Dim str As String str = Target Application.EnableEvents = False If Target <> "" Then If Len(str) = 7 Then Target = Left(str, 5) & "A" & Mid(str, 6, 1) & "-" & Right(str, 1) Else Target = Left(str, 5) & "A" & Mid(str, 6, 2) & "-" & Right(str, 1) End If End If Application.EnableEvents = True End Sub

  • エクセルVBAで重複入力の排除

    すでに入力規則はリストで使用しております。 そのためVBAで重複入力の排除を行おうと思います。 一応以下のコードでできたのですが、もっと良い方法があったら教えてください。 お願いいたします。 Private Sub Worksheet_Change(ByVal Target As Range)    Dim myDic As Object    Dim c As Variant, varData As Variant    Dim i As Long    If Application.Intersect(Target, Range("A1:A50")) Is Nothing Then Exit Sub    Set myDic = CreateObject("Scripting.Dictionary")    varData = Range("A1:A50").Value    For Each c In varData      If Not c = Empty Then        i = i + 1        If Not myDic.Exists(c) Then          myDic.Add c, Null        End If      End If    Next    If myDic.Count < i Then     MsgBox Target & " は重複!"     Application.EnableEvents = False     Application.Undo     Application.EnableEvents = True    End If End Sub

  • VBAで範囲を指定するには

    いつもお世話になります。 WINDOWS7 EXCELL2010 です。 下記のマクロを採用していますがその中に適用する範囲を指定したいのです。 指定する範囲は  I13~AM27 です。 どんな方法で追加すればいいかご教授を願えませんか。 Private Sub Worksheet_Change(ByVal Target As Range) Application.EnableEvents = False If Target.Value = 0 Then Target.Value = " " If Target.Value = 1 Then Target.Value = "日" If Target.Value = 2 Then Target.Value = "△" If Target.Value = 3 Then Target.Value = "▼" If Target.Value = 4 Then Target.Value = "前" If Target.Value = 5 Then Target.Value = "夜" If Target.Value = 6 Then Target.Value = "明" If Target.Value = 7 Then Target.Value = "有" Application.EnableEvents = True End Sub

  • excel 2007 VBA コードの記述

    Excel 2007 を使用しています。 TEST.xlsm というブック内に テスト01 というシートを作成し、そのタブを右クリックして コードの表示 を選択。 表示されたVBAコード入力シートに下記のコードを記述して使用してます。 Private Sub Worksheet_Change(ByVal Target As Range) 'この行から If Intersect(Target, Range("E3:E33,G3:G33,AH3:AH33,AJ3:AJ33,BK3:BK33,BM3:BM33")) Is Nothing Or Selection.Count <> 1 Then Exit Sub Application.EnableEvents = False If Target <> "" Then If IsNumeric(Target) Then Target = Target - 23 End If End If Application.EnableEvents = True End Sub 'この行まで この条件に新たに下記のコードを追加したいと思い ネット検索しながらあれこれ試行錯誤してますが まだまだVBA初心者のため上手く機能してくれません。 ※上のコードだけなら思った通りに機能します。 Private Sub Worksheet_Change(ByVal Target As Range) 'この行から If Intersect(Target, Range("Y3:Y33,BB3:BB33,CE3:CE33")) Is Nothing Or Selection.Count <> 1 Then Exit Sub Application.EnableEvents = False If Target <> "" Then If IsNumeric(Target) Then Target = Target - 30 End If End If Application.EnableEvents = True End Sub 'この行まで どなたかこれら二種のコードを一つにまとめた記述方法を 教えて頂けますでしょうか?

  • VBA Changeイベントのエラー

    エクセルで簡単な計算書を作成しています。(マクロ初心者) ちなみにこのコードは自分で作成したものではなく、人から聞いていじってみました。 Private Sub Worksheet_Change(ByVal Target As Range) '一度に複数セルの値が変更された場合は終了 '(A5:C5を選択しDeleteも含みます。) If Target.Count > 1 Then Exit Sub If Intersect(Target, Me.Range("H170:K170", "H171:K171","C76")) Is Nothing Then Exit Sub Application.EnableEvents = False '数値かつ空白以外の場合 If IsNumeric(Target.Value) And Target.Value <> "" Then Me.Range("M170").Formula = "=if(iserror(H170*I170*J170*K170),""-"",H170*I170*J170*K170)" '空白の場合 ElseIf Target.Value = "" Then Me.Range("H170:K170,M170").Value = "-" End If Application.EnableEvents = True Application.EnableEvents = False '数値かつ空白以外の場合 If IsNumeric(Target.Value) And Target.Value <> "" Then Me.Range("M171").Formula = "=if(iserror(H171*I171*J171*K171),""-"",H171*I171*J171*K171)" '空白の場合 ElseIf Target.Value = "" Then Me.Range("H171:K171,M171").Value = "-" End If Application.EnableEvents = True Application.EnableEvents = False '空白の場合 If Target.Value = "" Then Me.Range("D76:K76","C76").Value = "-" End If Application.EnableEvents = True End Sub H170、I170、J170、K170のどれかに数値の入力があった場合、M170に計算式を入力。 H170、I170、J170、K170のどれかの値をDELETEキーでクリアした場合、H170、I170、J170、K170、M170に"-"を入力。 その他に似たような処理がたくさん出てくるので、H171の処理とC76をDELETEキーでクリアした場合の処理を自分で考えて作ってみたのですが、うまく実行されません。H171~の処理はうまくいったので単純にコードをどんどん追加していけば動くと思ったんですが、いろいろ調べてもどうも方法がわからず進みません・・・ 解決してもらえるでしょうか・・

  • エクセル マクロ 初心者です

    エクセルマクロ初心者です。 以下の2つの Private Sub Worksheet_Change(ByVal Target As Range)を1つのシートで実行させたいのですが、 当方、初心者なので組み合わせ方が分かりません。 よろしくお願いします。 ===No1=== Private Sub Worksheet_Change(ByVal Target As Range) Application.EnableEvents = False Target = StrConv(Target, vbUpperCase) Application.EnableEvents = True End Sub ===No2=== Private Sub Worksheet_Change(ByVal Target As Range) Dim Ans As Integer If Target.Count = 1 Then Ans = MsgBox("コピーは禁止!!", vbCritical) MsgBox "データを消去します。" With Application .EnableEvents = False .Undo .EnableEvents = True End With End If If Target.Count = 1 Then Exit Sub Else MsgBox “複数セルのコピー禁止!" With Application .EnableEvents = False .Undo .EnableEvents = True End With End If End Sub ------------ 上記の2つを1つのシートで動作させたいのですが、うまくいきません。 単体では、動作します。

  • VBAの日付チェックでオーバーフローを回避したい。

    VBAの日付チェックでオーバーフローを回避したい。 ExcelのG列のセルに入力されたものが日付型であるかどうかのチェックかけたいと思います。 以下のコードだと、数字2958466以上の入力でオーバーフローが発生します。 これを回避する方法はありますか? セルを日付型に設定しているため、2958465(2999/12/31)までしか判別できないのでしょうが、 利用者が2958466以上を入力してしまう可能性はあります。 オーバーフローではなく、エラーメッセージが出せたら・・・と思います。 Private Sub Worksheet_Change(ByVal Target As Range) If Target.Column = 8 Then Application.EnableEvents = False If Target <> "" And Not IsDate(Target) Then MsgBox "日付型で入力してください。" & vbCrLf & "(例:2010/10/31)", vbCritical, "入力エラー" Target = "" Target.Select End If Application.EnableEvents = True End If End Sub こんなコードも試しましたが、結果は同じでした。 ↓ Private Sub Worksheet_Change(ByVal Target As Range) If Target.Column = 8 Then Application.EnableEvents = False If Target > 2958466 Then MsgBox "日付型で入力してください。" & vbCrLf & "(例:2010/10/31)", vbCritical, "入力エラー" Target = "" Target.Select Else If Target <> "" And Not IsDate(Target) Then MsgBox "日付型で入力してください。" & vbCrLf & "(例:2010/10/31)", vbCritical, "入力エラー" Target = "" Target.Select End If End If Application.EnableEvents = True End If End Sub On Error Resume Next や On Error GoTo ... での対処も考えましたが、同じ結果でした。 何か良い方法がありましたら、お願いいたします。

専門家に質問してみよう