2012-11-12 6 views
6

Ho scritto del codice VBA che accetta una singola cella e identifica tutti i suoi dipendenti nella cartella di lavoro (tramite un'analisi NavigateArrow) e aggiunge la loro posizione di intervallo a un array. Da qui voglio essere in grado di aggiornare ogni dipendente e modificare il riferimento alla singola cella originale in un'altra singola cella specificata.Sostituzione di dipendenti con un altro riferimento di cella in VBA

La difficoltà particolare che sto avendo qui è che sebbene io sappia dove è ogni dipendente, il riferimento alla cella originale può essere all'inizio, al centro o alla fine di una formula, e può essere disancorato, riga/colonna/entrambi ancorati, possono trovarsi su un foglio di lavoro diverso e quindi avere un riferimento al foglio di lavoro che lo precede, ecc. Quindi non posso trovare e sostituire facilmente in ogni cella dipendente, a causa di queste potenziali differenze, in più voglio mantenere il ancoraggio originale tenuto in ogni riferimento di cella.

Esiste una soluzione VBA elegante - o addirittura inelegante - a questo problema?

+1

Sembra che ci siano solo quattro varianti del riferimento/indirizzo che dovresti sostituire (riga relativa/fissa/colonna fissa/riga fissa + colonna), in modo da poterli scorrere tra tutti e sostituire se trovati (regolazione l'indirizzo sostitutivo di conseguenza) –

+0

Sì, non posso vedere in nessun altro modo, il che è un peccato perché sembra un po 'goffo. Grazie per l'aiuto! –

+0

Penso che quelle non siano le uniche varianti - non includerebbe anche gli intervalli denominati? O sono contati come riferimenti separati? –

risposta

1

Le espressioni regolari, o Regexp, sono ciò che state cercando, penso.

il seguente schema

([A-Z0-9]*)!(\${0,1})([A-Z]{1,3})(\${0,1})([0-9]*) 

corrisponderà nulla di simile "Sheet1! A1", "! $ A $ 1 Sheet1", "Sheet1! $ A1", "! A $ 1 Sheet1"

Spiegazione :

([A-Z0-9]*)! = Find anything that is before "!" 
(\${0,1}) = $ or nothing 
([A-Z]{1,3}) = between one and three letters 
([0-9]*) = Any number 

Si dovrebbe facilmente essere in grado di modificare quel modello per abbinare solo quello che vuoi. In particolare, ([A-Z0-9] *)! (\ $ {0,1}) B (\ $ {0,1}) 1, corrisponderà solo a qualcosa con B ($) 1 in esso ... Costruisci il pattern Regexp con la manipolazione delle stringhe e dovrebbe essere buono.

Avrai bisogno di fare riferimento (Strumento> Riferimento) "Microsoft VBScript Regular Expressions 5.5"

provare il seguente codice, questo dovrebbe dare tutti gli strumenti per raggiungere il tuo obiettivo

Sub ReplaceReference() 
' Reference: Microsoft VBScript Regular Expressions 5.5 

Dim RegEx As Object 
Set RegEx = New RegExp 

Dim s As String 

' Here I have hardcoded the reference to the original cell for demonstration purposes 
s = "Sheet1!$AB$2" 


' Replacement: New sheetname, New Column, new row number 
Dim NewCol As String, NewRow As String 
NewCol = "C" 
NewRow = "10" 

Dim NewSheet As String 
NewSheet = "Sheet2" 


With RegEx 
    .Pattern = "([A-Z0-9]*)!(\${0,1})([A-Z]{1,3})(\${0,1})([1-9]*)" 
    .IgnoreCase = True 
    .Global = True 
End With 


Debug.Print RegEx.Replace(s, NewSheet & "!" & "$2" & NewCol & "$4" & NewRow) 


End Sub 

Cheers, Julien

0

Perché non tagliare e incollare la cella di origine nella VBA? Quindi, Excel regolerà i riferimenti delle celle in tutta la loro gloriosa varietà.

Ho creato alcune celle con riferimenti e quindi ho utilizzato il registratore di macro per vedere cosa potrebbe accadere nel VBA generato quando si seleziona una cella, tagliare e copiare il contenuto. Il comportamento è come previsto, come segue:

Range("A1").Select 
Selection.Cut 
Range("B1").Select 
ActiveSheet.Paste 

Ciò si applica al seguente foglio di lavoro:

A1 1 
A2 =A1 
A3 =$A$1 
A4 =1+A1 
A5 =1+A1+1 

Dopo l'esecuzione della macro, tutti i riferimenti puntano alla cella B1 destinazione.