Macro VBA Impingindo entrada específica em uma célula com uma expressão regular

0

Eu preciso restringir o usuário quando ele tenta inserir alguma string em uma célula, esta entrada deve ser restrita à seguinte lista: C1, C2, C3, C4, C5, C6, C7, C8, C9 C10 ; palavras: mesclagem, enquadramento completo, largura, borda esquerda, borda direita e números inteiros de 1 a 100 por exemplo:
  C6 mesclar 1, C4 mesclar 1. Nenhum outro valor é permitido, exceto estes.

Ainda não consigo descobrir a regex exata que deve ser usada para incluir todas as regras acima. Aqui está o meu código:

Private Sub Worksheet_Change(ByVal Target As Range)


Dim strPattern As String
Dim regEx As RegExp
Dim vValues As Variant
Dim vValue As Variant
Dim strInput As String
Dim currCell As Range
Dim MyRange As Range

Set MyRange = ThisWorkbook.Worksheets("BY Blocks").Range("G3:G308")
    If Not Intersect(Target, Range("G:G")) Is Nothing Then
    strPattern = "the needed regex"
     'strPattern = "\b(C(?:10|[1-9])),(merge|complete framed|width),(\d+)"

    Set regEx = New RegExp

    vValues = Split(Target, ",")

    With regEx
     'For Each currCell In MyRange
           'If strPattern <> vbNullString Then
       ' strInput = currCell.Value
        'End If
              'Next currCell
        For Each vValue In vValues
            .Global = True
            .IgnoreCase = False
            .Pattern = strPattern

            If .Test(Trim(vValue)) Then
                MsgBox "Match found in " & Target.Value & " : " & Trim(vValue)
            Else
                MsgBox "No match"
            End If
     If (regEx.Execute(strInput)) Then
     '"smth when the pattern is matched"
     End If

     End With
     Set regEx = Nothing
     End If
      End Sub

Na verdade, o padrão de string está errado porque não encontra uma correspondência na condição If .Test (Trim (vValue))

    
por user3701825 29.05.2018 / 15:48

1 resposta

1

Aqui está uma abordagem que não usa Regex .

Em um módulo padrão, insira este UDF ()

Public Function IsItGood(aWord As Variant) As Boolean
    Dim s As String
    s = "|"
    tmp = s & aWord & s
    patern = ""

    For i = 1 To 100
        patern = patern & s & i
    Next i
    For i = 1 To 10
        patern = patern & s & "C" & i
    Next i
    patern = patern & s & "merge|complete framed|width|border left|border right" & s

    If InStr(1, patern, tmp) > 0 Then
        IsItGood = True
    Else
        IsItGood = False
    End If

End Function

Na área do código da planilha, digite:     Private Sub Worksheet_Change (ByVal destino como intervalo)         Dim BigS As String         Se Intersect (Range ("G: G"), Target) não é nada, então saia Sub         arr = Split (alvo, "")         Para cada um em arr             Se IsItGood (a) então             Outro                 MsgBox Target.Address (0, 0) & vbCrLf & um & vbCrLf & "tem coisas ruins"                 Application.Undo             Fim se         A próxima     End Sub

O código do evento recebe a entrada de frase da coluna G . Analisa a frase em palavras e certifica-se de que cada palavra é um membro da lista pré-definida.

EDIT # 1:

A versão anterior do código do evento permitia muitos UnDo s. Use esta versão:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim BigS As String

    If Intersect(Range("G:G"), Target) Is Nothing Then Exit Sub
    If Target.Count > 1 Then Exit Sub
    If Target.Value = "" Then Exit Sub
    arr = Split(Target, " ")
    For Each a In arr
        If IsItGood(a) Then
        Else
            MsgBox Target.Address(0, 0) & vbCrLf & a & vbCrLf & "has bad stuff"
            Application.EnableEvents = False
                Application.Undo
            Application.EnableEvents = True
            Exit Sub
        End If
    Next a
End Sub
  1. só será validado se uma única célula for alterada
  2. manipula melhor a limpeza de células
  3. limita o número de mensagens de erro
  4. elimina a causa do loop infinito ao desfazer
por 29.05.2018 / 18:37