Selezionare riga e colonna

Una sintesi di una richiesta di aiuto.

Da qualche giorno ho un problema che non riesco a risolvere. Vorrei contemporaneamente selezionare riga e colonna attive, però con questa semplice macro, attiva o riga o colonna, tutt'e due no. Saprebbe per caso modificare questa macro in modo da raggiungere quanto vorrei?

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Rows(Target.Row).Select
Target.Activate
Columns(Target.Column).Select
Target.Activate
End Sub

Inoltre c'è un problema: ad esempio se attivo la cella H11 io vorrei che attivasse appunto la cella H11 anche perchè se attivo quella è perché devo scriverci in quella. Ho provato a modificare la macro senza risolvere nulla (non capisco proprio niente di VBA).

 

La soluzione al problema

La routine presentata non può funzionare come richiede il lettore in quanto in quanto non seleziona contemporaneamente sia la riga che la colonna, ma prima seleziona la riga e poi la colonna, togliendo di fatto la precedente selezione alla riga.

La soluzione può essere la seguente, ma prima osserviamo le istruzioni usate nel codice:

Range("12:12,F:F").Select
Range("F12").Activate

dove 12:12 rappresenta la riga e F:F rappresenta la colonna ed F12 la cella di intersezione delle due selezioni.

Ma questa selezionerà sempre e comunque la riga 12 e la colonna F (la cella F12) rendendo attiva la cella di intersezione F12.

Per ottenere una selezione dinamica occorre sostituire ai valori assoluti delle variabili che verranno calcolate di volta in volta.

E' ovvio che per raggiungere il nostro scopo occorre trovare le due coordinate di riga e colonna.

Per fare questo ci affidiamo al'argomento Target dell'evento Worksheet_SelectionChange del foglio su cui stiamo lavorando.

L'argomento Target è in realtà una variabile di tipo Range che in questo caso ci può restituire tutte le proprità della cella in cui siamo e come tale lo possiamo interrogare e farci restituire le coordinate che esso rappresenta.

Per ottenere le due coordinate di riga e di colonna della cella in cui siamo approdati dopo uno spostamento possiamo usare questa:

A1 = Target.Address(0, 0)
R1 = Target.Row
C1 = Replace(A1, R1, "")

  1. con Target.Address(0, 0) otteniamo l'indirizzo dell'attuale cella attiva (ES:"F12")
  2. con Target.Row otteniamo il numero della riga (ES: 12)
  3. con Replace(A1, R1, "") otteniamo la lettera della colonna (ES: "F")

L'istruzione Replace esegue in una stringa una sostituzione di una sottostringa con un'altra come si vede da questo esempio: Replace("alfabeto", "a", "e") restituisce elfebeto

Nel nostro caso intendiamo eliminare la parte numerica (12) contenuta in A1 ("F12").

A questo punto siamo in grado di effettuare la nostra selezione:

Range(R1 & ":" & R1 & "," & C1 & ":" & C1).Select

che nel nostro caso equivale a:

Range("12:12,F:F").Select

Per rendere attiva la cella di intersezione tra la riga e la colonna l'istruzione sarà:

Range(Intersect(Range(R1 & ":" & R1), Range(C1 & ":" & C1)).Address).Activate

Con questo troviamo l'indirizzo della intersezione (F12)tra i due intervalli Range("12:12") e Range("F:F") e lo attiviamo. Attenzione però: in questo caso usiamo il metodo Activate anzichè il metodo Select per lasciare attiva la selezione precedentemente effettuata.

Questa è la selezione che intendiamo effettuare:

  A B C D E F G H I
1                  
2                  
3                  
4                  
5                  
6                  
7                  
8                  
9                  

 

Prima di concludere dobbiamo usare un ultimo accorgimento: disabilitare gli eventi con: Application.EnableEvents = False prima di effettuare la selezione e riabilitarli dopo con Application.EnableEvents = True per non entrare in un loop a causa dell'evento Worksheet_SelectionChange che viene evocato quando si effettua la selezione tramite l'esecuzione della routine del VBA.

La routine completa potrebbe essere questa.

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim A1, R1, C1
If Target.Count > 1 Then
ActiveCell.Select
Exit Sub
End If
A1 = Target.Address(0, 0)
R1 = Target.Row
C1 = Replace(A1, R1, "")
Application.EnableEvents = False
Range(R1 & ":" & R1 & "," & C1 & ":" & C1).Select
Range(Intersect(Range(R1 & ":" & R1), Range(C1 & ":" & C1)).Address).Activate
Application.EnableEvents = True
End Sub

Buon Lavoro.