You are on page 1of 197

EXCEL

CYCLOPEDIA
Sommario
AMBIENTE E INTERFACCIA UTENTE..........................................................................................8
Risposta in balloon a seconda del dato inserito................................................................................8
Inserimento di una pausa..................................................................................................................8
Input di un dato.................................................................................................................................8
Impedire la segnalazione di eventi da parte di Excel.......................................................................8
Conditionally Making a Sound.........................................................................................................8
Proteggere le celle............................................................................................................................9
Shading a Cell Until Something is Entered......................................................................................9
Shading Rows with Conditional Formatting..................................................................................10
Leaving a Cell Value Unchanged If a Condition Is False..............................................................11
Automatically Protecting After Input.............................................................................................12
Linking Comments to Multiple Cells.............................................................................................13
Using Data Forms...........................................................................................................................13
Creating a Splash Screen................................................................................................................14
Formatting Combo Box Text.........................................................................................................15
Magnifying Only the Current Cell.................................................................................................15
Returning Zero when a Referenced Cell is Blank..........................................................................17
Resizing Checkboxes.....................................................................................................................18
Usare il menu VAI A......................................................................................................................19
Speed up code and stop screen flickering:.....................................................................................19
Preventing calculation while executing code.................................................................................19
Speeding up code with Worksheet or Workbook Events. Also stops endless loops in Events......20
Mostrare tutte le icone (faceId) dei bottoni delle barre di Excel....................................................20
Creare ed eliminare via codice un riferimento ad una libreria.......................................................20
Controllare l’assistente di Office con VBA Excel.........................................................................21
FUNZIONE: Cambiare l’icona di Excel con VBA........................................................................21
Richiamare macro appartenenti ad altre cartelle............................................................................22
Nascondere e ripristinare barre e intestazioni di Riga e Colonna..................................................22
Changing an Invalid Autosave Folder............................................................................................22
Replacing Links with Values.........................................................................................................23
Determining if Calculation is Necessary........................................................................................24
Informazioni di sistema tramite VBA............................................................................................25
Ottenere informazioni sul sistema operativo..................................................................................26
Finding the Size of a Workbook.....................................................................................................26
Scrivere e utilizzare il registro di Windows con VBA...................................................................26
Creating a Sort Order.....................................................................................................................27
Changing Input Conventions..........................................................................................................28
Searching for Wildcards.................................................................................................................29
Changing Your Name.....................................................................................................................29
Fixing the Decimal Point................................................................................................................29
Unprotecting a Protected Worksheet..............................................................................................30
Displaying the Print Dialog Box in a Macro..................................................................................30
Finding the Path to the Desktop.....................................................................................................30
Automatically Loading Add-ins.....................................................................................................30
Excel Color Palette.........................................................................................................................31
List of Macro Shortcuts in All Open Workbooks..........................................................................34
Printing Multiple Worksheets on a Single Page.............................................................................35
Converting a Range of URLs to Hyperlinks..................................................................................37
Uncovering and Removing Links...................................................................................................38
Default Cell Movement when Deleting..........................................................................................38
Inserting the User's Name in a Cell................................................................................................39
Choosing Direction After Enter On a Workbook Basis.................................................................40
Changing Huge Numbers of Hyperlinks........................................................................................41
Locking All Non-Empty Cells.......................................................................................................42
Sharing Your Workbook................................................................................................................43
Tracking Down Invalid References................................................................................................44
Maintaining the Active Cell...........................................................................................................45
Excluding a Specific Add-In at Startup..........................................................................................47
Limiting Scroll Area.......................................................................................................................48
Setting the Default Font Size for Comment Balloons....................................................................48
Always Open at 100% Zoom.........................................................................................................49
Error Opening Second Workbook..................................................................................................50
DATABASE.......................................................................................................................................52
Importare dati dal web....................................................................................................................52
Connessione da Excel ad un database access con VBA.................................................................52
Creating a Photo Catalog from a Folder of Photos........................................................................53
Excel Applies Scientific Notation to Imported Data......................................................................55
Consolidare dati in base alla categoria...........................................................................................55
Synchronizing Lists........................................................................................................................56
Working with Record Numbers.....................................................................................................57
ELENCHI, FILTRI E ORDINAMENTO..........................................................................................59
Sorting Addresses by even and odd numbers.................................................................................59
Applicare il Filtro Automatico da worksheet e da VBA................................................................59
Copying the Results of Filtering....................................................................................................60
Working with Record Numbers.....................................................................................................60
Reorganizing Data..........................................................................................................................61
Sorting with Graphics.....................................................................................................................61
Showing Filter Criteria on a Printout.............................................................................................62
Ordinamento di range di dimensioni non determinate...................................................................64
Counting Groupings Below a Threshold........................................................................................64
Filtering Columns for Unique Values............................................................................................65
Excel Refuses to Put Page Breaks between Subtotal Groups........................................................66
Extracting Targeted Records from a List.......................................................................................66
Ordinamento con Bubble Sort........................................................................................................67
Extracting Proper Words................................................................................................................67
FILES E CARTELLE........................................................................................................................69
BrowseForFolder per cercare una cartella con VBA in Excel.......................................................69
Autodistruggi un file aperto...........................................................................................................69
FUNZIONE: verificare se una cartella esiste................................................................................69
Eliminare una cartella.....................................................................................................................69
Copiare una cartella e tutto il suo contenuto..................................................................................70
Spostare una cartella e tutto il suo contenuto.................................................................................70
Checking for the Existence of a File..............................................................................................70
Verifica se un file è aperto............................................................................................................71
Apertura di tutti i file di una directory...........................................................................................71
Looping Over Files with Dir, Through Files, Through Directories…...........................................72
Combining Worksheets from Many Workbooks...........................................................................72
Renaming a File..............................................................................................................................74
Filling References to Another Workbook......................................................................................74
Using Drag-and-Drop to Create a Hyperlink.................................................................................74
Aprire un file scelto dall’utente con estensione predeterminata....................................................75
Deleting a File in a Macro..............................................................................................................75
Running a Macro When a Workbook is Closed.............................................................................75
Searching a Workbook by Default.................................................................................................76
Comparing Workbooks..................................................................................................................76
Printing Workbook Properties........................................................................................................76
Importing Huge Data Files.............................................................................................................77
Aprire un file usando le wildcard...................................................................................................78
Use VBA SaveAs and CheckCompatibility in Excel 2007-2010..................................................79
FORMATTAZIONE (VBA)..............................................................................................................80
Formattazione di caratteri all’interno di un range..........................................................................80
Inversione di proprietà....................................................................................................................80
Changing Page Number Format.....................................................................................................80
Reversing Cell Contents.................................................................................................................81
Fare lampeggiare una cella.............................................................................................................81
FUNZIONE: Normalized number formats.....................................................................................83
FUNZIONE: Determining Font Formatting...................................................................................85
Replacing and Converting in a Macro............................................................................................86
Random Width and Height Changes..............................................................................................86
FORMATTAZIONE (WS)................................................................................................................88
Normalized number formats...........................................................................................................88
Superscripts in Custom Formats.....................................................................................................89
Flashing a cell using Conditional Formatting................................................................................89
Shading a Cell Until Something is Entered....................................................................................89
Shading Rows with Conditional Formatting..................................................................................90
Conditionally Formatting Non-Integers.........................................................................................91
Highlighting Cells Containing Specific Text.................................................................................92
Formatting Currency......................................................................................................................93
FORMULE E FUNZIONI (VBA).....................................................................................................94
FUNZIONE: Making VLOOKUP Case Sensitive.........................................................................94
Cancellare il contenuto di una cella fino ad una sequenza data di caratteri...................................94
FormulaR1C1 con riferimenti variabili..........................................................................................95
FUNZIONE: Conversione di riferimento R1C1 in A1..................................................................95
Funzione “CONTA.SE” in FormulaR1C1.....................................................................................95
Funzione “SOMMA.PIU.SE” in FormulaR1C1............................................................................95
FORMULE E FUNZIONI (WS)........................................................................................................96
Usare il NOME del FOGLIO.........................................................................................................96
Evitare Errori di ARROTONDAMENTO nelle Formule..............................................................96
CERCA.VERT...............................................................................................................................97
Making VLOOKUP Case Sensitive...............................................................................................98
Using VLOOKUP to Access Information to the Left....................................................................98
Calcolare la MEDIA dei numeri, ignorando i valori 0..................................................................99
Criteri multipli per CONTA.SE e SOMMA.SE (emula xxxx.PIU.SE di Excel 2007)..................99
Counting with Two Criteria...........................................................................................................99
Usare le SOMME 3D...................................................................................................................101
AUTORIEMPIMENTO con i Giorni della Settimana.................................................................101
Noting Inactivity within a Timeframe..........................................................................................101
Pasting Leading Zeroes................................................................................................................102
Easily Changing Links.................................................................................................................103
Nomi delle celle............................................................................................................................103
Copiare formule mantenendo i riferimenti relativi.......................................................................104
Incrementing References by Multiples when Copying Formulas................................................104
Random Numbers in a Range.......................................................................................................105
Recuperare il Tipo di oggetto selezionato....................................................................................105
Determining a Value of a Cell......................................................................................................106
Cancellare il contenuto di una cella fino ad una sequenza data di caratteri.................................106
Rounding to Even and Odd Values..............................................................................................106
Excluding Values from Averaging...............................................................................................107
Pasting Without Updating References.........................................................................................107
Finding the Directory Name.........................................................................................................108
GRAFICI E IMMAGINI..................................................................................................................109
Copiare un’immagine da un foglio ad un altro.............................................................................109
Automatically Updating Charts for Additional Data...................................................................109
Changing Elements in Lots of Charts at One Time......................................................................111
Reading Values from Graphs.......................................................................................................112
Easily Changing Chart Data Ranges............................................................................................112
Adding AutoShapes......................................................................................................................114
Specifying the Size of Chart Objects...........................................................................................115
Two-Level Axis Labels................................................................................................................115
Removing Pictures for a Worksheet in VBA...............................................................................116
Negatives in Pie Charts................................................................................................................117
INSERIMENTO E CONVALIDA DATI........................................................................................118
Verifica di input di un dato...........................................................................................................118
Creating Dependent Drop-Lists....................................................................................................118
Unique Name Entry......................................................................................................................119
Limiting Input to a Format...........................................................................................................120
Limiting Entry of Names..............................................................................................................121
Conditional Format that Checks for Data Type...........................................................................122
CONVALIDA di Dati di Latitudine in input...............................................................................123
Limiting Choices in a Cell............................................................................................................123
RANGES..........................................................................................................................................125
Avoid the use of Copy and Paste whenever possible...................................................................125
Inserting a Relative formula into a range of cells: Faster than AutoFill or Copy........................125
Autoriempimento di un Range con un pattern.............................................................................125
??????????????????????????........................................................................................................125
FUNZIONE: Trovare l’ultima riga o cella non vuota..................................................................126
Selezionare l’ultima cella non vuota del foglio............................................................................126
Seleziona l'ultima cella non vuota del foglio partendo dalla cella attiva.....................................126
Selecting the First Cell In a Row..................................................................................................126
Selezionare un range a partire da una cella singola......................................................................126
Incolla formula su un range e ne aggiunge la somma tipo R1C1.................................................127
Scopre e nasconde n colonne prima della cella attiva..................................................................127
Definizione di un intervallo come caratteristiche e area..............................................................127
Spostarsi sulla cella/riga successiva al range definito.................................................................127
Cancellazione del contenuto di un range......................................................................................128
Valorizzare un intervallo..............................................................................................................128
Copiare un intervallo....................................................................................................................128
Copia dei valori di un range da un foglio ad un altro...................................................................128
Cancellazione di righe consecutive..............................................................................................128
FUNZIONE: saltare le celle vuote nella definizione di un intervallo..........................................128
Using Named Ranges in a Macro.................................................................................................129
Relative VBA Selections..............................................................................................................129
Determining Rows and Columns in a Range...............................................................................130
Assegnare un valore a una cella distante saltando colonne nascoste...........................................130
Getting Rid of Empty Rows after Importing................................................................................130
DeleteRowOnCell........................................................................................................................131
Applying Range Names to Formulas...........................................................................................131
Copia delle sole celle visibili all’interno di un range...................................................................131
Positioning a Column on the Screen............................................................................................131
Flipping Data................................................................................................................................132
Highlighting the Rows of Selected Cells.....................................................................................133
Displaying a Set Column Range..................................................................................................134
FUNZIONE: Finding the Address of the Lowest Value in a Range............................................135
Comparing Lists for Duplicates...................................................................................................135
Deleting Duplicate Columns........................................................................................................136
Stepping Through a Non-Contiguous Range of Cells..................................................................137
Selecting Cells of a Specific Color...............................................................................................138
Relative References within Named Ranges.................................................................................139
TABELLE........................................................................................................................................141
Using a Macro to Select a Modified Table Body.........................................................................141
Spreading Out a Table..................................................................................................................141
Counting Unique Values..............................................................................................................142
Calculating the Interval Between Occurrences............................................................................143
Tables in Excel.............................................................................................................................144
TABELLE PIVOT...........................................................................................................................147
Inserire un campo calcolato in una Tabella Pivot........................................................................147
Formule dalle Tabelle Pivot.........................................................................................................147
Updating Multiple PivotTables at Once.......................................................................................147
Too Many Rows or Columns in a PivotTable..............................................................................148
Pointing PivotTables to Different Data........................................................................................148
Rows in a PivotTable...................................................................................................................149
TEMPO E DATE.............................................................................................................................150
Calculating Week-Ending Dates..................................................................................................150
Leap Years and Fiscal Periods.....................................................................................................150
Finding the Previous Work Day...................................................................................................151
Elapsed Days as Years, Months and Days...................................................................................152
Using the WEEKNUM Function.................................................................................................153
The Last Business Day.................................................................................................................153
Converting UNIX Date/Time Stamps..........................................................................................155
Using Excel for Timing................................................................................................................156
Finding the Date Associated with a Negative Value....................................................................156
Specifying Different Weekends with NETWORKDAYS...........................................................157
Adjusting Date Values by Keypress.............................................................................................158
Converting Coded Dates into Real Dates.....................................................................................159
Date for Next Wednesday............................................................................................................160
Calculating Averages by Date......................................................................................................160
Entering Large Time Values........................................................................................................162
TESTO E STRINGHE.....................................................................................................................164
Extracting a Pattern from within Text..........................................................................................164
FUNZIONE: Converting Numbers to Strings..............................................................................165
Creating a String of repeating characters in a Macro...................................................................165
Cleaning Text...............................................................................................................................166
Pulling Apart Cells.......................................................................................................................167
Delimited Text-to-Columns in a Macro.......................................................................................168
Sizing Text Boxes and Cells the Same.........................................................................................169
FUNZIONE: Eliminare caratteri iniziali fino a stringa predefinita.............................................170
WORKSHEETS...............................................................................................................................171
Referencing a Worksheet Name in cells and in VBA..................................................................171
Verifica l’esistenza di un foglio col nome dato............................................................................171
Rinomina fogli all’interno di un array di file...............................................................................172
Protezione e sprotezione di ogni foglio della cartella..................................................................172
Un foglio molto nascosto.............................................................................................................172
Combining Worksheets from Many Workbooks.........................................................................173
Running a Macro When a Worksheet is Deactivated...................................................................173
Sorting Data on Protected Worksheets.........................................................................................174
Crack Sheet Protection Password.................................................................................................175
Locking Worksheet Names..........................................................................................................176
Running Macros on Hidden Worksheets......................................................................................176
Creating Worksheets with a Macro..............................................................................................177
Condensing Multiple Worksheets Into One.................................................................................177
GESTIONE ERRORI.......................................................................................................................179
Gestione degli errori.....................................................................................................................179
Finding and Replacing Error Values............................................................................................179
VARIABILI......................................................................................................................................181
Use VbNullString to get a String variable back to its default value............................................181
Release memory from Object variables:......................................................................................181
Quickly Dumping Array Contents...............................................................................................181
INTEGRAZIONE OFFICE..............................................................................................................183
Getting Excel Dates into Outlook's Calendar...............................................................................183
Dynamic Hyperlinks in Excel......................................................................................................184
Creazione batch di email in Outlook............................................................................................184
Conversione di un range in formato HTML (Funzione)..............................................................186
Invio dei messaggi contenuti nella cartella “Bozze” di Outlook..................................................187
Nascondere l’apertura di Excel da parte di applicazione esterna.................................................187
Aggiungere alle date la notazione ordinale inglese......................................................................188
GENERALITA’...............................................................................................................................190
Metodi e Proprietà nel VBA di EXCEL.......................................................................................190
Variabili........................................................................................................................................190
CORRISPONDENZA FUNZIONI ITALIANO - INGLESE.........................................................191
AMBIENTE E INTERFACCIA UTENTE
Risposta in balloon a seconda del dato inserito
Sub Response(bln As Balloon, lbtn As Long, lPriv As Long)
    bln.Close
    Select Case lbtn
        Case Is = 1
            MsgBox "Riposati", vbInformation
        Case Is = 2
            MsgBox "Che aspetti. Inizia", vbCritical
        Case Is = 3
            MsgBox "Chiama tre amici e tira fuori il risiko", vbInformation
    End Select
End Sub

Inserimento di una pausa


Sub Attendi()
Dim PauseTime, Start, Finish, TotalTime
If (MsgBox("Scegliere Sì per interrompere l'applicazione per 5 secondi",
4)) = vbYes Then
PauseTime = 5   
' Imposta la durata.
Start = Timer   
' Imposta l'ora di inizio.
Do While Timer < Start + PauseTime
(' Passa il controllo ad altri processi.)
Loop
Finish = Timer   
' Imposta l'ora di fine della pausa.
TotalTime = Finish - Start    '
Calcola il tempo totale.
MsgBox "Interruzione di " & TotalTime & " secondi"
Else
End
End If
End Sub

Input di un dato
Sub Inputbox_con_variabile()
Dim MyVar As String
MyVar = Inputbox("prova messaggio con variabile")
End Sub

Impedire la segnalazione di eventi da parte di Excel


Application.DisplayAlerts = False

Conditionally Making a Sound


Summary: Need to have a sound played if a certain condition is met? There is no way to do this
without resorting to using macros. If you just want to make a beep sound, you can use something
like this:

Function BeepMe() As String


Beep
BeepMe = ""
End Function

All this user-defined function does is to play a sound (which will vary depending on the system you
are using) and then return an empty string. You can use the function in your worksheet in this
manner:

=IF(A12>300,BeepMe(),"")

If you want to play some sound other than the default system beep, you'll need to use the Windows
API PlaySound function. The following code creates a user-defined function that will play the
default "tada" sound so prevalent in Windows.

Private Declare Function PlaySound Lib "winmm.dll" _


Alias "PlaySoundA" (ByVal lpszName As String, _
ByVal hModule As Long, ByVal dwFlags As Long) As Long

Const SND_SYNC = &H0


Const SND_ASYNC = &H1
Const SND_FILENAME = &H20000

Function SoundMe() As String


Call PlaySound("c:\windows\media\tada.wav", _
0, SND_ASYNC Or SND_FILENAME)
SoundMe = ""
End Function

This function can be called the same as the previous example:

=IF(A12>300,SoundMe(),"")

If you want to play a different WAV file, simply change the file specification in the SoundMe
function.

Proteggere le celle
Excel permette di proteggere le celle e i dati in modo semplice ed efficace. E’ necessario prima di
tutto identificare quali celle devono essere lasciate libere da vincoli: di default quando si attiva la
funzione di protezione le celle sono tutte bloccate, perciò non sarà possibile utilizzare alcuna cella.
Una volta identificate le celle da lasciare libere, selezionarle e premere Ctrl+1, quindi nella scheda
"Protezione" togliere la spunta alla casella "Bloccata". In questo modo quando il foglio verrà
bloccato, l'effetto sarà su tutte le celle tranne quelle selezionate. A questo punto si può andare su
Strumenti e scegliere "Protezione”.

Shading a Cell Until Something is Entered


When creating a worksheet in which information must be entered into specific cells, you may find it
helpful to shade the cells if they are blank, but have the shading removed if something is entered
into the cell. You can easily accomplish this task by using the conditional formatting feature in
Excel.

Follow these steps if you are using Excel 2007:


1. Select the cells to which the conditional formatting should apply.
2. Display the Home tab of the ribbon.
3. Click the Conditional Formatting tool in the Styles group. Excel displays a list of
conditional formatting options.
4. Choose New Rule. Excel displays the New Formatting Rule dialog box.
5. In the list of rule types, select Use a Formula to Determine which Cells to Format. In the
formula area, enter the following formula, replacing A1 with the address of the active cell
selected in step 1:

=ISBLANK(A1)
6. Click Format to display the Format Cells dialog box.
7. Click the Fill tab.
8. Select the color you want used for shading the cell if it is blank.
9. Click OK to dismiss the Format Cells dialog box. The shading color you selected in step 9
should now appear in the preview area for the rule. Click OK again.

Follow these steps, instead, if you are using an older version of Excel:

1. Select the cell or cells that you want shaded if they are empty.
2. Choose Conditional Formatting from the Format menu. Excel displays the Conditional
Formatting dialog box.
3. Use the Condition drop-down to choose Formula Is.
4. In the formula area, to the right of the drop-down list used in step 3, enter the following
formula, replacing A1 with the address of the active cell selected in step 1:

=ISBLANK(A1)
5. Click Format to display the Format Cells dialog box.
6. Click the Patterns tab.
7. Select the color you want used for shading the cell if it is blank.
8. Click OK to dismiss the Format Cells dialog box. The shading color you selected in step 7
should now appear in the preview area for the condition. Click OK again.

All the empty cells among those selected in step 1 should now appear shaded. When you enter
something into one of the shaded cells, the shading should disappear.

Shading Rows with Conditional Formatting


One way to use conditional formatting is to cause Excel to shade every other row in a table. This is
great when you have a particularly wide table, and you want to make it a bit easier to read on
printouts. Simply follow these steps if you are using Excel 2007:

1. Select the table whose alternate rows you want to shade.


2. Make sure the Home tab of the ribbon is displayed.
3. Click the Conditional Formatting tool. Excel displays a series of choices.
4. Click New Rule. Excel displays the New Formatting Rule dialog box.
5. In the Select a Rule Type area at the top of the dialog box, choose Use a Formula to
Determine Which Cells to Format.
6. In the formula space, enter the following formula:

=MOD(ROW(),2)=0

7. Click on the Format button. Excel displays the Format Cells dialog box.
8. Make sure the Fill tab is selected.
9. Select the color you want used for the row shading, then click OK twice

Those familiar with Excel 2007 may wonder why anyone would use conditional formatting to
highlight different rows of a table when you can use the table formatting feature (available in the
Styles group of the Home tab of the ribbon) to accomplish the same thing. The reason is simple—
using conditional formatting provides much more flexibility in the formatting applied as well as in
the interval of the rows being shaded.

If you are using an older version of Excel then there is no style to provide alternate-row formatting,
so you must use conditional formatting. Follow these steps:

1. Select the table whose alternate rows you want to shade.


2. Choose Conditional Formatting from the Format menu. Excel displays the Conditional
Formatting dialog box.
3. Using the pull-down condition, select Formula Is. Excel changes the dialog box controls to
reflect your choice. In the formula box, enter the following:

=MOD(ROW(),2)=0

4. Click on the Format button. Excel displays the Format Cells dialog box.
5. Make sure the Patterns tab is selected.
6. Select the color you want used for the row shading, then click OK twice.

Leaving a Cell Value Unchanged If a Condition Is False


The IF function can take up to three parameters. The first parameter is the comparison that is to be
made, the second parameter is what should be returned if the comparison is true, and the third is
what should be returned if the comparison is false. It is possible to leave off the last parameter, but
if you do then Excel will return the value 0 if the comparison is false.

The obvious solution, then, is to make sure that you provide the IF function with something that
should be returned when the comparison is false. For instance, let's say that your formula is in cell
B1 and you are comparing something in cell A1. The formula you use may look like this:

=IF(A1<10,"under ten",B1)

Note that the words "under ten" are returned if the value in A1 is less than 10. If this condition is
not met, then the value in B1 is returned. Since this formula is in cell B1, this means that the
previous value in the cell is returned if the condition is false.

It also means that the formula contains a circular reference. For circular references to work OK you
need to let Excel know that it is OK for them to occur in your worksheet. Choose Tools | Options |
Calculation tab and make sure the Iteration check box is selected. Excel will now allow the circular
reference without complaint.

If you don't want to allow a circular reference in your worksheet, then the only recourse is to create
a macro that updates the value in cell B1 based upon any changes to cell A1:

Private Sub Workbook_SheetChange(ByVal Sh As Object, _


ByVal Target As Range)
' See if the change is related to our cell
If Not (Application.Intersect(Target, Range("A1")) _
Is Nothing) Then
If Range("A1") < 10 Then
Range("B1") = "under ten"
End If
End If
End Sub

This simple macro, when added to the ThisWorkbook module, is executed every time there is a
change in the workbook. If the value is cell A1 is changed (and only that cell), then the value is
checked to see if it is less than 10. If it is, then the value in cell B1 is changed. If it isn't, then the
value in cell B1 is left alone.

There is one "gottcha" that you need to keep in mind with any of the approaches discussed thus far,
formula or macro. If the value in cell A1 is (let's say) 15, then cell B1 will contain what was there
before, whatever it was. If you change the value in cell A1 to (let's say) 7, then B1 will change to
"under ten." That's fine, but from that point on cell B1 will never appear to change. Why? Because
if you then change cell A1 to a value greater than 10, cell B1 will contain (as just explained) what
was there before. And, as you now understand, the value that was there before is the result of the
previous true result, which was "under ten." Thus, true or false, the formula or macro from this
point on displays the text "under ten."

Automatically Protecting After Input


Excel offers protection for your worksheets, meaning that you can protect the contents of cells so
they cannot be changed. Exactly how you use this protection has been discussed in other issues of
ExcelTips. What if you want to allow cells to be edited, but you want them to become protected
right after someone enters information in the cell? For instance, you have cells in which a user
could enter information, but once entered, you don't want them to have the ability to change the
information they entered.

There is no inherent ability in Excel to protect your input, but you can create the ability through the
use of a macro. The following macro is an example of how you can do this:

Private Sub Worksheet_Change(ByVal Target As Range)


Dim MyRange As Range

Set MyRange = Intersect(Range("A1:D100"), Target)


If Not MyRange Is Nothing Then
Sheets("Sheet1").Unprotect password:="hello"
MyRange.Locked = True
Sheets("Sheet1").Protect password:="hello"
End If
End Sub

This macro assumes that the worksheet has already been protected, and that all the cells where you
want input to be possible are unlocked. What it does is check to see if the input was done in the
proper range of cells, in this case somewhere in the range of A1:D100. If it was, then the worksheet
is unprotected, the cell in which information was just entered is locked, and the worksheet is again
protected.

If you are using this approach in your own workbook, you will need to modify the potential input
range, and you will want to change the password used to unprotected and protect the worksheet.
Linking Comments to Multiple Cells
When you insert a comment into a worksheet, that comment is associated with a single cell. doesn't
provide the capability to have a single comment associated with two or more cells. You can achieve
this using a text box to contain the comment, and then draw lines between the text box and
whatever cells the comment applies to. If you normally want your comments hidden, then you will
need to use a macro that takes care of making the text box and lines visible or invisible.

For instance, assume that you create a comment in a text box named Text Box 1. Further, assume
that you have two lines leading from the text box to the cells to which the comment applies. The
first line, named Line 1, leads to cell C15. The second line, named Line 2, leads to cell F7. You
could add the following macro to the worksheet's object:

Private Sub Worksheet_SelectionChange(ByVal Target As Excel.Range)


Shapes("Text Box 1").Visible = False
Shapes("Line 1").Visible = False
Shapes("Line 2").Visible = False

If Target.Address = "$C$15" Then


Shapes("Text Box 1").Visible = True
Shapes("Line 1").Visible = True
End If
If Target.Address = "$F$7" Then
Shapes("Text Box 1").Visible = True
Shapes("Line 2").Visible = True
End If
End Sub

Anytime a selection is made on the worksheet, the three objects are hidden. If cell C15 is selected,
the textbox and the line appropriate line are made visible. Similarly, if cell F7 is selected, the
textbox and its line are made visible.

Using Data Forms


A data form is used to allow easy manipulation of information in an Excel data list. While a list is
small - for instance, when it fits on one screen - it is easier to enter or change information directly.
When you start getting a larger number of records, then you may find using a data form to be easier.

A data form is a dialog box that displays one complete record from your list at a time. Excel
considers a record to be a single row in your data list, so a data form basically extracts the
information from a row, uses the field labels from the first row of the list, and displays the
information so you can understand it easier. To utilize a data form, follow these two simple steps:

1. Select a cell (any cell) within your data list.


2. Choose the Form option from the Data menu. Excel displays the data form from your list.
The above steps won't work with Excel 2007, however. The reason is that the Form option is
not available on any of the ribbon tabs. To use the form capabilities of Excel, you'll need to
add the option to the Quick Launch Toolbar by following these steps:

1. Click the Office button and then click Excel Options. The Excel Options dialog box appears.
2. At the left side of the dialog box, click Customize.
3. Using the Choose Commands From drop-down list, choose Commands Not in the Ribbon.
4. Scroll through the list of commands and select the Form command.
5. Click the Add button. The Form command now appears at the right side of the dialog box.
6. Click OK. The Form command now appears on the Quick Access Toolbar.

You can now use a data form in Excel 2007 by selecting any cell within your data list and clicking
the Form icon on the Quick Access Toolbar. A data form, similar to those used in earlier versions of
Excel, appears.

There are several important items to note when working with data forms. The title that appears at
the top of the data form is taken directly from the name of the worksheet on which the data resides.
If you want to change the title, simply change the name of the worksheet tab.

The field labels are listed down the left side, and you can input information to the right of these
labels. If a field contains a formula, you cannot enter information in that field; it is calculated
automatically.

You can move between entry fields by pressing the Tab key. When you press Enter, any changes
you make are saved in the record. The buttons at the right side of the data form are used to navigate
through the list. If you click your mouse on the Close button, the data form is removed and you are
returned to your worksheet.

Notice that there are several searching buttons located along the right side of the data form. The
Find Prev and Find Next buttons are used to step through your list. If you click on the Criteria
button, you can enter information that will be used by the other search buttons (Find Prev and Find
Next) when displaying records.

Creating a Splash Screen


For those who are creating their own applications in Excel, user forms are a common way of
presenting information to users. You can even create a basic splash screen through a user form, but
getting rid of some of the normal trappings of a dialog box (like the close button), is not immediate.

There is no direct way to remove the close button from a user form, but it can be done with an API
call. You can find additional information on how to do this (it is rather involved) at this Web site
created by Stephen Bullen. Scroll most of the way down the page and look for the file called
"NoCloseButton.zip."

http://www.bmsltd.co.uk/Excel/SBXLPage.asp

Instead of relying on Windows API calls, you can simply disable the close button so it has no effect.
You can do this using this type of code:

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)


If CloseMode = 0 Then
Cancel = True
End If
End Sub
Formatting Combo Box Text
If you insert objects, such as a combo box, in your worksheet, you may need a way to modify the
font used in the object. The ability to make such changes depends on the type of object you are
inserting. You can use the Forms toolbar to add a combo box to your worksheet, or the Developer
tab of the ribbon in Excel 2007.

You can control many attributes of the combo box (right-click it and choose Format Control), but
you cannot change the attributes of the font used to display information in the combo box. This
seems to be an odd oversight on the part of Microsoft, but it has been that way since the earliest
days of the Forms controls.

If you want greater control over how the combo box looks, then you will need to skip the Forms
controls and instead add one from the Control Toolbox. You can display this toolbox by choosing
Toolbars from the View menu, and then choosing Control Toolbox. If you are using Word 2007
then you can see the same controls by displaying the Developer tab of the ribbon and then clicking
Insert. (In Excel 2007 the Control Toolbox controls are called ActiveX controls.)

The controls available in the Control Toolbox look very similar to the Forms controls. The Control
Toolbox controls, while they have the same names as the Forms controls, are quite different. For
instance, you can place a combo box, but it looks a bit different than the one you place using the
Forms controls. In addition, you can select a newly placed combo box and then click Properties to
see all the attributes you can change—there are quite a few more of them when you add a combo
box in this manner.

So what differences are there between the two ways of adding a combo box? Besides appearance
and a richer set of properties, there isn't a whole lot of difference. There is one operational
difference—you can insert a combo box from the Forms controls onto a chart sheet, but you cannot
do so from the Control Toolbox.

Magnifying Only the Current Cell


Let’s assume that you are working on a worksheet which needs to be at a low zoom setting (30% or
so) to see the whole sheet. As different scenarios are run, cells change color depending on the result.
You can easily see which cells he needs to investigate, but can't read them because of the zoom
setting. Instead of changing the zoom, read the answer, and zoom back out to run another scenario,
it would be much easier if only the current cell (the one selected) were magnified to a readable
level.

There is no built-in method in Excel to accomplish this selective method of zooming, but there are a
couple of workarounds you can use. One such workaround is to use a macro that displays the value
in the active cell in a message box. Such a macro is easy to add to the worksheet module:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)


MsgBox ActiveCell.Address & ": " & ActiveCell.Value
End Sub

Every time you select a different cell in the worksheet, the macro pops up a message box that shows
the contents of that cell. This solves the problem, but it can get tiresome to continually close
message boxes every time you change which cell is selected.
You could also create a macro that simply changed the font size of whatever cell is currently
selected. The following simple macro, added to the worksheet module, looks at the currently
selected cell and increases its font size by 500%.

Private Sub Worksheet_SelectionChange(ByVal Target As Range)


FontSize = ActiveCell.Font.Size
LargeSize = FontSize * 5
Cells.Font.Size = FontSize
ActiveCell.Font.Size = LargeSize
End Sub

The utility of such a macro will depend, of course, on how you have the height and width of the
selected cell formatted. If they are static heights and widths, it is possible that increasing the font
size will make the cell contents unreadable. If the height and width are dynamic, then the contents
should still be quite readable.

Still another approach is to create your own zoomed-in picture of each cell as it is selected. The
following macro does this:

Private Sub ZoomCell(ZoomIn As Single)


Dim s As Range
Set s = Selection

'Get rid of any existing zoom pictures


For Each p In ActiveSheet.Pictures
If p.Name = "ZoomCell" Then
p.Delete
Exit For
End If
Next

'Create a zoom picture


s.CopyPicture Appearance:=xlScreen, _
Format:=xlPicture
ActiveSheet.Pictures.Paste.Select
With Selection
.Name = "ZoomCell"
With .ShapeRange
.ScaleWidth ZoomIn, msoFalse, _
msoScaleFromTopLeft
.ScaleHeight ZoomIn, msoFalse, _
msoScaleFromTopLeft
With .Fill
.ForeColor.SchemeColor = 9
.Visible = msoTrue
.Solid
End With
End With
End With
s.Select
Set s = Nothing
End Sub

In order to use the macro, you need to call it each time the selection in the worksheet changes. To
do this, you add a small macro to the worksheet module:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)


ZoomCell 6
End Sub
In this case, every time the cell selection is changed, the ZoomCell macro is run to create a picture
that is six times the size of the original. If it gets bothersome to have the picture automatically
change every time you select a different cell, you could do away with the trigger macro in the
worksheet module and modify the ZoomCell macro so that it runs whenever you initiate it, perhaps
with a shortcut key that you set up.

Sub ZoomCell()
Dim s As Range
Dim ZoomIn As Single
Set s = Selection
ZoomIn = 6

'Get rid of any existing zoom pictures


For Each p In ActiveSheet.Pictures
If p.Name = "ZoomCell" Then
p.Delete
Exit For
End If
Next

'Create a zoom picture


s.CopyPicture Appearance:=xlScreen, _
Format:=xlPicture
ActiveSheet.Pictures.Paste.Select
With Selection
.Name = "ZoomCell"
With .ShapeRange
.ScaleWidth ZoomIn, msoFalse, _
msoScaleFromTopLeft
.ScaleHeight ZoomIn, msoFalse, _
msoScaleFromTopLeft
With .Fill
.ForeColor.SchemeColor = 9
.Visible = msoTrue
.Solid
End With
End With
End With
s.Select
Set s = Nothing
End Sub

A final option is to step outside of Excel entirely and rely on Windows. One of the accessibility
tools provided with the operating system is called Magnifier. The program magnifies the area near
the mouse pointer, overlaying another area of the screen with the enlarged image. You can use this
tool by choosing Start | All Programs | Accessories | Accessibility | Magnifier. You'll see the
magnified area appear at the top of your screen, and a dialog box that allows you to set different
options for the program. When you no longer need the magnification, you can turn it off by clicking
Exit on the dialog box.

Returning Zero when a Referenced Cell is Blank


If you have a formula in a worksheet, and the cell referenced by the formula is blank, then the
formula still returns a zero value. For instance, if you have the formula =A3, then the formula
returns the contents of cell A3, unless cell A3 is blank. In that case, the formula returns a value of
zero.This seems to be related to the idea that it is impossible for a formula to return a blank value,
when "blank" is used synonymously with "empty." You can, however, expand your formula a bit so
that it returns an empty string. Instead of using =A3 as your formula, you would use the following:

=IF(ISBLANK(A3),"",A3)

This formula uses ISBLANK, which returns either True or False, depending on whether the
referenced cell (A3) is blank or not. The IF function then returns an empty string ("") if A3 is blank,
or it uses the value in A3 if A3 is not blank.

Regardless of what the formula returns, you can still use its result in other formulas, and it will
work fine. Even if it returns an empty string, it is still treated by other formulas as if it contained
zero. In areas where treating the cell as if it contained zero might be problematic (such as when you
are charting the results of the formula), then you can modify the formula a bit, as shown here:

=IF(ISBLANK(A3),NA(),A3)

This formula returns the #N/A error if A3 is blank. This error propagates through other formulas
that reference the formula, but the #N/A error is ignored completely when charting.

While the above solutions are satisfactory for most people, some people would really like to see a
target cell be truly blank if the source cell is blank. For instance, you might want cell B7 to be blank
if cell A3 is blank. If you put a formula in cell B7 (as already discussed), then cell B7 is not truly
blank—it contains a formula.

If this is your goal—true "blankness"—then you can only achieve it through the use of a macro. The
macro will need to check to see if the source cell was changed. If it was, then whatever is in the
source needs to be copied to the target cell.

Private Sub Worksheet_Change(ByVal Target As Excel.Range)


Dim rMonitor As Range
Dim rTarget As Range

Set rMonitor = Range("A3")


Set rTarget = Range("B7")

If Not Intersect(Target, rMonitor) Is Nothing Then


rMonitor.Copy rTarget
End If

Set rMonitor = Nothing


Set rTarget = Nothing
End Sub

Resizing Checkboxes
When working in VBA, one of the things you can create is known as a "user form." These forms
provide you with the ability to essentially create your own dialog boxes. You can add many
different types of controls to a user form, if desired. For instance, you can add labels, text boxes,
drop-down lists, radio buttons, and many other controls. Some of the controls you can resize; others
you cannot. One that you cannot resize is a checkbox. While you can modify the font size used for
the label next to the checkbox, you cannot resize the checkbox itself.
If you find the checkboxes in your user forms too small for your taste, you can "work around" them
by simulating a checkbox. You do this by actually creating a label instead of a checkbox. Then,
change the properties of the label so that it has a transparent background, and that the font being
used is Wingdings. You should also make sure that the font is set to a large size, such as 20 or 26
points.

Now, double-click on your label, which should open a code window. The event that you are
programming is the Click event for the label, which means it will be executed whenever the label is
clicked. Use this as your code:

Private Sub Label1_Click()


If Label1.Caption = Chr(254) Then
Label1.Caption = Chr(168)
Else
Label1.Caption = Chr(254)
End If
End Sub

In the Wingding font, Chr(254) is box with a checkmark, and Chr(168) is a box with no checkmark.
When you execute the user form and click on the label, it switches between an empty box and a
checked box. You can also add other code to the Click event that performs other tasks, as necessary.

Usare il menu VAI A


La finestra di dialogo VAI A si trova sotto il menu Home – Trova e Seleziona (Modifica in Excel
2003) e può essere richiamata con il tasto F5.
La funzione primaria è permettere di selezionare una o più celle. Possiamo digitare "A500" nella
casella "Riferimento", oppure, se vi fossero presenti dei Nomi, potremmo fare clic sul nome.
Possiamo anche selezionare dei range. Per farlo, dobbiamo fare clic su "Speciale...": in questo menu
possiamo selezionare determinate celle. In particolare, possiamo attivare tutte le celle contenenti dei
commenti, oppure tutte quelle che contengono del testo: per quest’ultimo caso, dovremo spuntare la
casella Costanti e lasciare spuntata solo la casella Testo. Excel mostra tutte le celle del foglio non
generate da formule (=costanti) che contengono del testo.
Supponiamo di voler selezionare tutte le celle vuote di un'area per poter assegnare a esse un colore
differente. Per farlo basterà spuntare la casella Celle Vuote dal menu VAI A - SPECIALE. Se
invece vogliamo selezionare un'area contigua dovremo spuntare Zona Corrente.

È possibile selezionare tutte le celle dipendenti o precedenti verso una certa cella. A differenza di
altri tool, in questo caso potremo SELEZIONARE le celle e non solo di visualizzarle.
Con il menu Speciale possiamo anche scoprire quali celle contengono delle Formattazioni
Condizionali (menu Formato), oppure quali zone del foglio contengono delle opzioni Convalida
Dati (strumento del menu Dati). Per eliminare le immagini provenienti da pagine Html che vengono
incollate nel foglio, basterà selezionarle con VAI A - SPECIALE / OGGETTI e premere CANC

Speed up code and stop screen flickering:


Application.ScreenUpdating=False

Application.ScreenUpdating=True
Preventing calculation while executing code
Application.Calculation = xlCalculationManual

Application.Calculation = xlCalculationAutomatic

Speeding up code with Worksheet or Workbook Events. Also stops endless loops
in Events

Application.EnableEvents = False

Application.EnableEvents = True

Mostrare tutte le icone (faceId) dei bottoni delle barre di Excel


Sub listAllFaces()
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim cbCtl As CommandBarControl
Dim cbBar As CommandBar

On Error GoTo Recover


Application.ScreenUpdating = False

Set cbBar = CommandBars.Add(Position:=msoBarFloating, MenuBar:=False,


temporary:=True)
Set cbCtl = cbBar.Controls.Add(Type:=msoControlButton, temporary:=True)
k = 1

Do
    For j = 1 To 15
    i = i + 1
    Application.StatusBar = "Face ID=" & i
    cbCtl.FaceId = i
    cbCtl.CopyFace
    ActiveSheet.Paste Cells(k, j + 1)
    Cells(k, j).Value = i
    Next j
    k = k + 1
Loop

Recover:
If Err.Number = 1004 Then Resume Next
Application.StatusBar = False
cbBar.Delete
End Sub

Creare ed eliminare via codice un riferimento ad una libreria


Sub Add_External_Reference_()
   Dim rVBReference As VBIDE.Reference
   Dim wbBook As Workbook

   Const stGuid As String = "{420B2830-E718-11CF-893D-00A0C9054228}"   


'GUID Microsoft Scripting Runtime.
   Const stName As String = "MS Scripting Runtime"

   Set wbBook = ThisWorkbook


   On Error GoTo Error_Handling

   With wbBook
      For Each rVBReference In .VBProject.References
         If rVBReference.GUID = stGuid Then
            MsgBox "La libreria di " & stName & " è già attiva!", _
vbInformation
            GoTo ExitHere
         End If
      Next rVBReference
        .VBProject.References.AddFromGuid stGuid, 1, 0
       MsgBox "La reference " & stName & " è stata creata!", vbInformation
      GoTo ExitHere
   End With
ExitHere:
   Set rVBReference = Nothing
   Exit Sub
Error_Handling:
   MsgBox "Impossibile creare la reference  " & stName & vbCrLf & " poiché non
esiste su questo PC.", vbCritical
   Resume ExitHere
End Sub

Sub Delete_Reference()
   Dim wbBook As Workbook
   Const stDescription As String = "Scripting"
   Set wbBook = ThisWorkbook
   On Error GoTo Error_Handling
   With wbBook.VBProject.References
      .Remove .Item(stDescription)
   End With
    MsgBox "Reference rimossa!", vbInformation
ExitHere:
   Exit Sub
Error_Handling:
   MsgBox "Reference non esistente!", vbInformation
   Resume ExitHere
End Sub

Controllare l’assistente di Office con VBA Excel


Sub OfficeAssistant()
    With Assistant
        .Visible = True
        With .NewBalloon
            .Heading = "Come ti aiuto?"
            .Labels(1).Text = "Sono stanco"
            .Labels(2).Text = "Ho troppi compiti"
            .Labels(3).Text = "Voglio giocare"
            .BalloonType = msoBalloonTypeButtons
            .Button = msoButtonSetNone
            .Mode = msoModeModeless
            .Callback = "Response"
            .Show
        End With
    End With
End Sub

FUNZIONE: Cambiare l’icona di Excel con VBA


Option Explicit
Declare Function GetActiveWindow32 Lib "USER32" Alias _
                                   "GetActiveWindow" () As Integer
Declare Function SendMessage32 Lib "USER32" Alias _
                     "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, _
                                          ByVal wParam As Long, ByVal lParam As
Long) As Long
Declare Function ExtractIcon32 Lib "SHELL32.DLL" Alias _
        "ExtractIconA" (ByVal hInst As Long, ByVal lpszExeFileName As String, _
                                              ByVal nIconIndex As Long) As Long

Sub ChangeApplicationIcon()
      Dim Icon&
     
      '*****Change Icon To Suit*******
      Const NewIcon$ = "notepad.exe"
      '*****************************
      Icon = ExtractIcon32(0, NewIcon, 0)
      SendMessage32 GetActiveWindow32(), &H80, 1, Icon      '< 1 = big Icon
      SendMessage32 GetActiveWindow32(), &H80, 0, Icon      '< 0 = small Icon
End Sub

Richiamare macro appartenenti ad altre cartelle


Sub Esegui_altre_macro()
    Application.Run "Cartel1.xls!NomeMacro"
End Sub

Nascondere e ripristinare barre e intestazioni di Riga e Colonna


Private Sub Workbook_SheetActivate (ByVal Sh As Object)
With Application
.CommandBars(1).Enabled = Not Sh.Name = “Sheet1”
.CommandBars(“Formatting”).Enabled = Not Sh.Name = “Sheet1”
.DisplayFormulaBar = Not Sh.Name = “Sheet1”
End With
ActiveWindow.DisplayHeadings = Not Sh.Name = “Sheet1”
End Sub

Changing an Invalid Autosave Folder


Summary: Excel allows you to specify where it stores various files used by the program. One
location you can specify is where Autosave files should be saved. If you specify a folder that later
becomes unavailable, however, you could end up with a headache. (This tip works with Microsoft
Excel 97, Excel 2000, Excel 2002, Excel 2003, and Excel 2007.)

Michael's laptop used to be connected to a business LAN and he used mapped drives (O:, P:, etc.)
for file saves. He is no longer on the network, and Excel has remembered a P:\Autosave folder
destination for Autosave, which is no longer valid. Michael can't pull up the dialog box to change
the file location, as he gets an error message every time saying "Can't access directory
P:\Autosave". Michael wonders if there is another way to modify his Autosave folder location.

There are several ways you can go about trying to change this. One method is to simply "map"
another drive so that the operating system directs any request for drive P: to that drive. There are
various methods to do this, such as using the SUBST command. This is an old DOS command that
allows a folder (such as C:\MyFolder\MyTemp or some other name) to be "substituted" for a drive
letter. Just create the temporary folder and then use the following at the command prompt:

subst P: c:\myfolder\mytemp
You can then access the P: drive (which is really the folder), create the Autosave folder within it,
start Excel, make your folder change, and exit Excel. When you want to get rid of the mapping, use
the following at the command prompt:

subst P: /d

You can then get rid of the temporary folders you created. Another way to accomplish the same
result is to use the NET USE command. Create the temporary folders, as described above, and then
share them on your network. (Right-click the folder in a Windows Explorer window and specify it
should be shared.) You can then map the drive by using the following at the command line:

net use P: \\ComputerName\ShareName

In this instance you need to replace "ComputerName" with the name of your computer and
"ShareName" with the name under which you shared the folder. After the command is successfully
used, then all references to P: will redirect to the shared folder. When you are done making the
changes you need, use the following command-line command to get rid of the share:

net use P: /delete

You could also try to map a drive by using a USB drive. Use the disk management tools in the
Control Panel to change the drive letter of the USB drive to P:. Once this is done you can easily
change the Autosave directory in Excel.

If you don't want to take the route of mapping a new drive, you can always try to edit the Registry.
Try examining the data in the following key to see if you can locate the folder designation:

HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Excel\Options
You'll need to change the key name depending on your version of Excel; this example is for Excel
2003. All you need to do is change the "11.0" portion to reflect the version you are using. (Look for
the AutoRecoverPath key.) If you locate the path to the Autosave folder in the key, simply delete it
or change it to point to an available path.

Replacing Links with Values


Summary: Need to get rid of the links in your workbook but save the values that were retrieved by
those links? It could be easy or hard, depending on the complexity of your workbook. Here are
some great ideas you can try. (This tip works with Microsoft Excel 97, Excel 2000, Excel 2002,
Excel 2003, and Excel 2007.)

One thing to try is to open the workbooks that contain the links and then use Excel's tools to break
the links. Make sure you keep a backup of your workbook (in case you mess things up) and follow
these steps if you are using Excel 2007:

1. Click the Office button, then click Prepare | Edit Links to Files. Excel displays the Edit
Links dialog box.
2. Select the links in the dialog box.
3. Click Break Links and acknowledge that you really want to break the selected links.
4. Click OK.

In an older version of Excel you should follow these steps:


1. Open the workbook you want to affect.
2. Choose the Links option from the Edit menu. Excel displays the Links dialog box.
3. Select the links in the dialog box.
4. Click Break Links and acknowledge that you really want to break the selected links.
5. Click OK.

The result is that all the links are done away with, but the values last retrieved through the links
remain in the workbook.

Another approach is to use Paste Special to "overwrite" your links. (This works well if you have a
limited number of links in a worksheet.) Follow these steps:

1. Select the cells that contain links.


2. Press Ctrl+C.
3. Display the Paste Special dialog box in Excel 2007 by starting at the Home tab of the
ribbon, clicking the down-arrow under the Paste tool, and then choosing Paste Special. In
older versions of Excel just choose Edit | Paste Special.
4. Click the Values radio button.
5. Click OK.

If you have quite a few links in your workbook, then you will want to use a macro to do the link
breaking. The following is an example of a simple macro to do the breaking:

Sub BreakLinks()
Dim aLinksArray As Variant

aLinksArray = ActiveWorkbook.LinkSources(Type:=xlLinkTypeExcelLinks)
Do Until IsEmpty(aLinksArray)
ActiveWorkbook.BreakLink Name:=aLinksArray(1), _
Type:=xlLinkTypeExcelLinks
aLinksArray = _
ActiveWorkbook.LinkSources(Type:=xlLinkTypeExcelLinks)
Loop
End Sub

It is important to remember, though, that links can be tricky. Links to other workbooks can be in
formulas, names, charts, text boxes, and other objects, both visible and hidden, and in different
combinations within formulas and those objects. Getting all the links and breaking them depends on
the complexity of your workbook. If you have a complex workbook, then you may benefit by using
the FindLink add-in created by Excel MVP Bill Manville. You can find it here:

http://www.bmsltd.co.uk/MVP/

Determining if Calculation is Necessary


Summary: When processing a worksheet with a macro, it may be helpful to periodically
recalculate the worksheet. Wouldn't it be nice if you could only recalculate if Excel tells you that
recalculation is necessary? Here's some ideas on how you can figure out when you need to do a
recalc. (This tip works with Microsoft Excel 97, Excel 2000, Excel 2002, Excel 2003, and Excel
2007.)

Excel allows you to control when it recalculates a worksheet. Normally, Excel recalculates anytime
you change something in a cell. If you are working with very large worksheets that have lots of
formulas in them, you may want to turn off the automatic recalculation feature. You can turn off
automatic recalculation using controls on the Calculation tab of the Options dialog box.

Your macros can also force Excel to recalculate your worksheet. If you have automatic
recalculation turned on, then any change your macro makes in a worksheet will force Excel to
recalculate. If you have automatic recalculation turned off, then you can use the Calculate method
to recalculate a worksheet:

ActiveSheet.Calculate

Of course, if recalculation takes quite a while to perform, you might want to check to see if a
recalculation is necessary before actually forcing one. It appears that there is no flag you can
directly check to see if a recalculation is necessary. The closest thing is to check the Workbook
object's Saved property. This property essentially acts as a "dirty flag" for the entire workbook. If
there are unsaved changes in a workbook, then the Saved property is False; if everything is saved,
then it is True.

How does this help you figure out if a recalculation is necessary? Remember that calculation is only
necessary when there are changes in a worksheet. Changing anything in a worksheet will also set
the workbook's Saved property to False. Thus, you could check the Saved property before doing the
recalculation, as shown here:

If Not ActiveWorkbook.Saved Then


ActiveSheet.Calculate
End If

There is only one problem with this approach, of course—the Saved property is only set to True if
the workbook is actually saved. This means that you could recalculate multiple times without really
needing to do so, unless you tie saving and recalculation together, as shown here:

If Not ActiveWorkbook.Saved Then


ActiveSheet.Calculate
ActiveWorkbook.Save
End If
The wisdom of approaching this problem in this manner depends on the nature of your particular
situation. If it takes longer to save the workbook than it does to simply recalculate, then this
approach won't work. If, however, recalculation takes longer (which is very possible with some
types of operations), then this approach may work well.

Informazioni di sistema tramite VBA


Sub OperatingSystem()
Debug.Print "------------------------------------------------------------"
Debug.Print Application.OperatingSystem
Debug.Print Application.Name
Debug.Print Application.LibraryPath
Debug.Print Application.MemoryTotal
Debug.Print Application.MemoryUsed
Debug.Print Application.MemoryFree
Debug.Print Application.StartupPath
Debug.Print Application.UILanguage
Debug.Print Application.UsableHeight
Debug.Print Application.UsableWidth
Debug.Print Application.WindowsForPens
Debug.Print Application.Version
Debug.Print Application.Build
Debug.Print Application.OrganizationName
Debug.Print Application.UserName
Debug.Print "xlCountrycode : " & Application.International(xlCountryCode)
Debug.Print "xlCountrySetting : " & Application.International(xlCountrySetting)
Debug.Print "xlNonEnglishFunctions : " &
Application.International(xlNonEnglishFunctions)
Debug.Print "xlMetric : " & Application.International(xlMetric)
Debug.Print "xlCountrySetting : " & Application.International(xlCountrySetting)
Debug.Print "------------------------------------------------------------"
End Sub

Ottenere informazioni sul sistema operativo


La funzione che assolve a questo compito si chiama INFO(argomento) e ha un unico argomento,
che può assumere i seguenti valori (da racchiudere tra virgolette):

 “directory” restituisce il percorso della cartella corrente


 “mem_tot” visualizza la memoria totale disponibile in byte inclusa la memoria utilizzata
 “mem_usata” visualizza la quantità di memoria utilizzata per i dati
 “memdispo” restituisce la quantità di memoria disponibile in byte
 “numfile” mostra il numero di fogli di lavoro attivi nelle cartelle di lavoro aperte
 “origine” crea un riferimento assoluto di tipo A1 come testo, preceduto da "$A:" che
rappresente il riferimento alla cella visibile più in alto e a sinistra in base alla posizione di
scorrimento corrente
 “ricalc” visualizza la modalità di ricalcolo Excel corrente. Riporta Automatico o Manuale
 “sistema” restituisce il nome dell'ambiente operativo: Macintosh = mac, Windows = pcdos
 “versione” riporta la versione di Microsoft Excel come testo
 “versione_os” visualizza la versione del sistema operativo corrente come testo

Finding the Size of a Workbook


Function wbksize()
myWbk = Application.ThisWorkbook.FullName
wbksize = FileLen(myWbk)
End Function

To use this macro within a worksheet, just type the following in any cell:

=wbksize()

The file size is displayed in bytes.

Scrivere e utilizzare il registro di Windows con VBA


In questo esempio l'istruzione SaveSetting viene innanzitutto utilizzata per creare voci nel registro
di Windows o nel file .ini in piattaforme Windows a 16 bit per l 'applicazione MyApp. L'istruzione
DeleteSetting viene quindi utilizzata per eliminarle

Sub SalvaSettings()
'Inserisce alcune impostazioni nel registro.
SaveSetting appname:="MyApp", Section:="Startup", Key:="Top", setting:=75
SaveSetting "MyApp", "Startup", "Left", 50

'Rimuove la sezione e tutte le impostazioni dal registro.


DeleteSetting "MyApp", "Startup"
End Sub

Nell’esempio che segue l'istruzione SaveSetting viene innanzitutto utilizzata per creare voci nel
registro di Windows per l'applicazione specificata dall'argomento appname. La funzione
GetAllSettings viene quindi utilizzata per visualizzare le impostazioni. Si noti che non è possibile
utilizzare la funzione GetAllSettings per recuperare i nomi di applicazione e i nomi di sezione.
'L'istruzione DeleteSetting viene infine utilizzata per eliminare le voci relative all'applicazione.

Sub GetTuttiSettingdiUnAppl()
' Variabile Variant per archiviare la matrice bidimensionale restituita
da GetAllSettings.
' Valore Integer per memorizzare il contatore.
Dim MySettings As Variant, intSettings As Integer
' Inserisce alcune impostazioni nel registro.
SaveSetting appname:="MyApp", Section:="Startup", Key:="Top", setting:=75
SaveSetting "MyApp", "Startup", "Left", 50
' Legge le impostazioni.
MySettings = GetAllSettings(appname:="MyApp", Section:="Startup")
    For intSettings = LBound(MySettings, 1) To UBound(MySettings, 1)
        Debug.Print MySettings(intSettings, 0), MySettings(intSettings, 1)
    Next intSettings
DeleteSetting "MyApp", "Startup"
End Sub

Creating a Sort Order


For instance, let's assume you have a field that can contain the name of one of four colors - Black,
Red, Green, and Orange - and that you wanted your list sorted in that order. The problem is, Excel
would normally sort this list alphabetically - Black, Green, Orange, and Red. The solution is to
create a custom list that has the color names in the order you desire.

To create a custom list, follow these steps if you are using Excel 2007:

1. Click the Office button and then click Excel Options. Excel displays the Excel Options
dialog box.
2. Make sure Popular is selected at the left of the dialog box.
3. Click Edit Custom Lists. Excel displays the Custom Lists dialog box and hides the Excel
Options dialog box.
4. Select the NEW LIST option from the Custom Lists list at the left of the dialog box.
5. In the List Entries portion of the dialog box, start typing the order in which you want the
elements sorted.
6. When you are done, click the Add button.
7. Repeat steps 4 through 6 to define any other lists desired, then click OK to finish.

If you are using a version of Excel prior to Excel 2007 follow these steps instead:

1. Select Options from the Tools menu. Excel displays the Options dialog box.
2. Make sure the Custom Lists tab is selected.
3. Select the NEW LIST option from the Custom Lists list.
4. In the List Entries portion of the dialog box, start typing the order in which you want the
elements sorted.
5. When you are done, click the Add button.
6. Repeat steps 3 through 5 to define any other lists desired, then click OK to finish.
In steps 5 or 4 (depending on your version of Excel) you need to enter information in the List
Entries area of the dialog box. For this example you would type the following:

Black
Red
Green
Orange

Make sure you press Enter at the end of each element and that what you type matches exactly the
possible contents of the sorting field. Once your lists are defined, you can use them to sort as
described in other ExcelTips.

Changing Input Conventions


Different cultures have different conventions for displaying numbers and for parameters in Excel's
worksheet functions. Here's how you can change which conventions Excel uses. A partial solution
for the decimal point and separators in numbers can be realized by overriding, within Excel, the
symbols used for the decimal point and thousands. Follow these steps in Excel 2007:
1. Click the Office button and then click Excel Options. Excel displays the Excel Options
dialog box.
2. At the left of the dialog box click Advanced.
3. Scroll down until the Editing section is displayed. Uncheck the checkbox for Use System
Separators.
4. Enter the desired separators for Decimal and Thousands.
5. Click OK.

If you are using an older version of Excel, follow these steps:

1. Choose Options from the Tools menu. Excel displays the Options dialog box.
2. Make sure the International tab is displayed.
3. Uncheck the checkbox for Use System Separators.
4. Enter the desired separators for Decimal and Thousands.
5. Click OK.

This will not solve the entire problem, however. The better solution is to leave Excel unchanged and
make your configuration changes in Windows itself. Follow these general steps:

1. Open the Control Panel.


2. Open the Regional and Language Options applet and display the Regional Options tab.
3. Change the language setting in the drop-down menu from Italian (Italy) to English (United
Kingdom).
4. If you can't change the language setting (some implementations of Windows are a pain), you
may need to experiment a bit and change the settings for the decimal and thousands
separators.

You may have to restart Excel for these changes to be fully implemented.

Searching for Wildcards


You know that you can use Excel's Find and Replace feature to locate information in your
workbooks. (Just press Ctrl+F or Ctrl+H to pull up the dialog box.) You can use question marks
(?) and asterisks (*) as wildcard characters, just as you would at a DOS command prompt. What if
you want to search for a cell that actually contains an asterisk or a question mark, however?

Excel allows you to search for special characters by preceding the character with the tilde (~). In
other words, if you want to search for an asterisk, you would actually search for ~*. If you wanted
to search for the question mark, you would search for ~? instead.

Finally, if you wanted to search for the tilde character, you would actually search for ~~. In each
instance, the leading tilde informs Excel that the following character should be translated as an
actual character, and not as a special wildcard character.

Changing Your Name


When you first install Excel, it asks you for your name so it can personalize the registration for your
program. It also writes your name into the user area. This information is used in various places by
Excel, such as in the workbook properties area. If you need to change your name, follow these steps
if you are using Excel 2007:
1. Click the Office button and then click Excel Options. Excel displays the Excel Options
dialog box.
2. Make sure the Popular option is selected at the left of the dialog box. (It should be selected
by default.)
3. Change the information in the User Name box, as desired.

If you are using an older version of Excel, follow these steps:

1. Choose Options from the Tools menu. You will see the Options dialog box.
2. Make sure the General tab is selected.
3. Change the information in the User Name box, as desired.

Fixing the Decimal Point


Most desktop electronic calculators have an option that allows you to specify a fixed location for a
decimal point. This comes in real handy when you are working with dollars and cents, for instance.
With the decimal point fixed at two places, you can enter "213" and have the calculator translate it
as "2.13". Likewise, if you enter "2", the calculator translates it as "0.02".

Excel has a feature that allows you to do the same thing. To fix the number of decimal places
assumed when inputting information, follow these steps:

1. Choose Options from the Tools menu. Excel displays the Options dialog box.
2. Make sure the Edit tab is selected.
3. Make sure the Fixed Decimal check box is selected.
4. Using the Places control, specify how many decimal places Excel should assume.

Unprotecting a Protected Worksheet


When you protect a worksheet, you can't use some tools, including the spell-checker. If you want to
use it, you must unprotect the worksheet, run the check, and then protect it again. In order to have a
macro complete these steps, you must know the password used to protect the worksheet. The
following example checks the selected cell and assumes that the password is "mypass."
Sub SpellCheckCell()
With ActiveSheet
.Unprotect ("mypass")
Selection.CheckSpelling
.Protect ("mypass")
End With
End Sub

Displaying the Print Dialog Box in a Macro


If you are creating a macro that is used to print information from your worksheets, you may want to
display the Print dialog box. The user can then choose to print, directly from within your macro. To
add this capability, simply include the following macro line:

bTemp = Application.Dialogs(xlDialogPrint).Show

The Show method results in the Print dialog box being displayed. When this code line is finished,
bTemp will be either True or False. If True, it means that the user clicked on OK in the dialog box,
thereby printing something. If False, then the user either clicked on Cancel or the Close button to
close the dialog box without printing.

Finding the Path to the Desktop


There are several ways to find the path to the desktop in VBA. One way is to call the Windows
scripting host, in this manner:

Function GetDesktop() As String


Dim oWSHShell As Object

Set oWSHShell = CreateObject("WScript.Shell")


GetDesktop = oWSHShell.SpecialFolders("Desktop")
Set oWSHShell = Nothing
End Function

Note that this is a user-defined macro that you can use either from the worksheet or from another
macro. The use from the worksheet would be as follows:

=GetDesktop()

Another way to determine the path to the desktop is to use the following line in your code:

sPath = Environ("USERPROFILE") & "\Desktop"

Automatically Loading Add-ins


Summary: Want to load a particular add-in for use with a specific worksheet? Open the VBA
Editor and put the following code in the “This Workbook” section:

Private Sub Workbook_BeforeClose(Cancel As Boolean)


AddIns("Add-In Name").Installed = False
End Sub
Private Sub Workbook_Open()
AddIns("Add-In Name").Installed = True
End Sub

In the code, change the name of the add-ins (“Add-In Name”) to the real name of the add-in you
want to use with the worksheet.

If you are not sure of the correct name for a particular add-in, use the macro recorder to record the
process of activating an add-in. That will show you the exact name you should use in the above
macros.

Excel Color Palette


Excel Color Palette has an index of 56 colors which can be modified using VBA. Each color in the
palette is associated with a unique value in the index that can be changed programatically. At times
it is useful to know the relative positioning of the various colors within this index as well as how
various versions of Excel treat colors.

This macro generates a color palette and place it an Excel 2003 or earlier worksheet :

Sub colors56()
'57 colors, 0 to 56

Dim i As Long
Dim str0 As String, str As String
Cells(1, 1) = "Interior"
Cells(1, 2) = "Font"
Cells(1, 3) = "HTML"
Cells(1, 4) = "RED"
Cells(1, 5) = "GREEN"
Cells(1, 6) = "BLUE"
Cells(1, 7) = "COLOR"

For i = 0 To 56
    Cells(i + 2, 1).Interior.ColorIndex = i  
    Cells(i + 2, 2).Font.ColorIndex = i
    Cells(i + 2, 2).Value = "[Color " & i & "]"
    str0 = Right("000000" & Hex(Cells(i + 2, 1).Interior.Color), 6)
    'Excel shows nibbles in reverse order so make it as RGB
    str = Right(str0, 2) & Mid(str0, 3, 2) & Left(str0, 2)
    'generating 2 columns in the HTML table
    Cells(i + 2, 3) = "#" & str
    Cells(i + 2, 4).Formula = "=Hex2dec(""" & Right(str0, 2) & """)"
    Cells(i + 2, 5).Formula = "=Hex2dec(""" & Mid(str0, 3, 2) & """)"
    Cells(i + 2, 6).Formula = "=Hex2dec(""" & Left(str0, 2) & """)"
    Cells(i + 2, 7) = "[Color " & i & "]"
Next i
End Sub

The output of the code will be something akin to what is shown below.
(Please note: Values -1 and 0 can be assigned to an object. However you cannot change those
color values in the palette which would lead me to assume that Excel provides 58 (56 + 2)
assignable color values while there being only 56 modifiable color values.)

The interesting thing is that there seems to be no apparent logic to the allocation of color index
values to various colors - it neither proceeds from light (#FFFFFF) to dark (#000000) nor follow a
sequential numbering pattern in the palette (left to right or up to down).
The following code allows to assign
a new color to the palette at a
particular index position by
specifying the index number and
then using the .Colors function to
assign a new RGB value to it. The
R, G and B signify the red, green
and blue hues that make up the
color. (You can get the color index
from the index chart shown above)

Sub change_palette_color
    dim color_index as long
    color_index = 10
    ActiveWorkbook.Colors(color_index) = RGB(128, 128, 128)
End sub

Excel 2007 handles color in a completely different manner. The color palette theme can be changed
by accessing the “Colors” option under the “Page Layout” ribbon.

You can also define new color combinations (or select from a host of pre-existing ones) by using
the options provided under this menu. The good part is that the color combinations are not just a
mix of the existing 56 colors but new colors, which means that when you choose a new color theme,
the RGB values of the new colors are different from the ones you had previously.

The number of colors in the color index


remains the same at 56. However additional
properties such as .ThemeColor and
.TintAndShade enable to work with nearly
unlimited colors. This is a major improvement
over Excel 2003 which used to “snap” custom
colors to the ones which were already existing
in the palette. Therefore, a piece of code would
generate different results in Excel 2003 and
2007:

Sub test_color()
For i = 1 To 256
   Cells(i, 1).Interior.Color =
RGB(i, i, i)
Next i
End Sub

As you can see, in Excel 2007 there is a smooth gradient


from the darkest to the lightest hue while in Excel 2003, the
colors change in bands.
As I said before, you can use the .ThemeColor and .TintAndShade properties to change color
tint and theme:

Sub test_color()
For i = 1 To 256
    Cells(i, 1).Interior.ThemeColor = xlThemeColorAccent1
    Cells(i, 1).Interior.TintAndShade = (i * 2 - 256) / 256
Next i
End Sub

(Just bear in mind that you can enter a number from -1 (darkest) to 1 (lightest) for the
TintAndShade property with 0 (zero) being neutral. Attempting to set this property to a value less
than -1 or more than 1 results in a run-time error: “The specified value is out of range.” This
property works for both theme colors and nontheme colors.)

List of Macro Shortcuts in All Open Workbooks


The easiest way to list all yours macros, along with the shortcut keys used to initiate them, would be
to create a macro that exported each of your macros to a .bas text file, then read that text file to
determine the shortcut keys. Why this is easiest is because the shortcut keys are not directly
available to VBA, but they are written as part of the text file whenever you export macros.

For instance, when you export a macro to a .bas file, it will include lines similar to the following:

Attribute VB_Name = "Module1"


Attribute MyMacro.VB_Description = "My Description"
Attribute MyMacro.VB_ProcData.VB_Invoke_Func = "q\n14"

Your macro could read the .bas file (it is nothing but a text file) and parse what is written there to
extract the macro's name and shortcut keys. In the above example, "Module1" is the module the
code is in, "MyMacro" is the procedure name, "My Description" is the description for the procedure
and "q" is the shortcut key. (The "\n14" seems to be there for all macros; what it signifies is
unclear.)

Your code, to be effective, would need to loop through all the modules in a workbook, doing the
export and parse steps to get the desired information.

Sound complex? It can be. It's a good thing that there is already a macro available that does all of
this. Ivan Moala has written a free Excel add-in that does exactly what is described above. The add-
in is available here:

http://www.xcelfiles.com/GetShortCutKeys.html

The code is password protected but Moala has indicated elsewhere on the Internet that the password
to access the code is "test." By unlocking the code, you can see exactly how he achieved his results
and then create your own macro, or you can just modify his to make sure that whatever is printed
matches your needs. For instance, if you want the macro to print the workbook name, module name,
macro name, and shortcut key, then you could modify the code to do exactly that.

There is one gottcha that could bite you when using macros of this sort, as well. You need to make
sure that you have your macro security set to the proper level to allow the type of access required
for the macro to do its work. You do this by choosing, within Excel, Tools | Options | Security |
Macro Security. (In Excel 2007 you display the Developer tab of the ribbon, then click Macro
Security in the Code group.) You can then set the security level to the necessary setting: Trust
Access VB Projects or, in Excel 2007, Trust Access to the VBA Project Object Model.

The code described so far allows you to get the desired information for a specific workbook. The
next step, of course, is to make sure that the code is applied to each open workbook. This is
relatively easy. If your code to process the macros in a single workbook is named something like
ListKeys, then you can create a different macro that looks like this:

Sub ListAllKeys()
Dim wkb As Workbook

For Each wkb In Workbooks()


Call ListKeys(wkb)
Next
End Sub

The macro steps through all the open workbooks, passing each one's name to the ListKeys macro.
This name can then be used by your ListKeys procedure to determine where it grabs its information
from.

Printing Multiple Worksheets on a Single Page


Workbooks can contain all sorts of data. If you have a workbook that includes a number of
worksheets, each containing only a small amount of data, you may wonder if there is a way to print
the multiple worksheets on a single sheet of paper.

There are a couple of ways that you can approach a solution to this problem. The first is simply
print multiple pages per sheet, using the capabilities of your printer driver. For instance, I have an
older HP LaserJet, and the printer driver allows me to specify the number of pages to print per sheet
of paper. If I wanted to print three or four single-page worksheets all on one piece of paper, all I
need to do is follow these steps:

1. Choose Print from the File menu. Excel displays the Print dialog box.
2. In the Print What area of the dialog box, choose the Entire Workbook option.
3. Click the Properties button. Excel displays the Properties dialog box for the printer, with the
Layout tab selected.
4. Set the Pages Per Sheet control to 4.

Your printer may offer a similar capability to what is outlined here, but you may need to do some
exploring through the printer's Properties dialog box to find that capability. Of course, printing this
way can lead to some very small text on the printout, because the printer driver simply reduces each
page to occupy a proportionate area of the printed page. If you want to reduce some of the white
space, and thereby increase the size of the printed text, then you need to look for a different
solution.

Many people, to consolidate what is printed, actually create a "printing worksheet" which contains
nothing but references to the areas to be printed on the other worksheets in the workbook. These
references can either be done through formulas referring to the data on each worksheet, or by using
the camera tool in Excel. (The camera tool has been described in other issues of ExcelTips.)
For an automated solution of amalgamating multiple worksheets into a single worksheet, you can
use a macro. The following macro will create a new worksheet at the end of your workbook and
copy the contents from all the other worksheets into it.

Sub PrintOnePage()
Dim wshTemp As Worksheet, wsh As Worksheet
Dim rngArr() As Range, c As Range
Dim i As Integer
Dim j As Integer

ReDim rngArr(1 To 1)
For Each wsh In ActiveWorkbook.Worksheets
i = i + 1
If i > 1 Then ' resize array
ReDim Preserve rngArr(1 To i)
End If

On Error Resume Next


Set c = wsh.Cells.SpecialCells(xlCellTypeLastCell)
If Err = 0 Then
On Error GoTo 0

'Prevent empty rows


Do While Application.CountA(c.EntireRow) = 0 _
And c.EntireRow.Row > 1
Set c = c.Offset(-1, 0)
Loop

Set rngArr(i) = wsh.Range(wsh.Range("A1"), c)


End If
Next wsh

'Add temp.Worksheet
Set wshTemp = Sheets.Add(after:=Worksheets(Worksheets.Count))

On Error Resume Next


With wshTemp
For i = 1 To UBound(rngArr)
If i = 1 Then
Set c = .Range("A1")
Else
Set c = _
ActiveSheet.Cells.SpecialCells(xlCellTypeLastCell)
Set c = c.Offset(2, 0).End(xlToLeft) 'Skip one row
End If

'Copy-paste range (prevent empty range)


If Application.CountA(rngArr(i)) > 0 Then
rngArr(i).Copy c
End If
Next i
End With
On Error GoTo 0

Application.CutCopyMode = False ' prevent marquies

With ActiveSheet.PageSetup 'Fit to 1 page


.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = 1
End With

'Preview New Sheet


ActiveWindow.SelectedSheets.PrintPreview

'Print Desired Number of Copies


i = InputBox("Print how many copies?", "ExcelTips", 1)
If IsNumeric(i) Then
If i > 0 Then
ActiveSheet.PrintOut Copies:=i
End If
End If

'Delete temp.Worksheet?
If MsgBox("Delete the temporary worksheet?", _
vbYesNo, "ExcelTips") = vbYes Then
Application.DisplayAlerts = False
wshTemp.Delete
Application.DisplayAlerts = True
End If
End Sub

After the combined worksheet is put together, the macro displays the worksheet using Print
Preview. When you close Print Preview, it asks how many copies of the worksheet you want to
print. If you enter a number greater than zero, then that many copies are printed. Finally, the macro
offers to delete the combined worksheet for you just before finishing.

Converting a Range of URLs to Hyperlinks


Converting a single URL into a hyperlink is easy. Converting hundreds or thousands can be much
harder if you have to rely on manual methods.

As is the case with most tedium in Excel, the solution is to use a macro to do the conversion. To be
effective, the macro would need to step through each cell in a selected range and, if the cell is not
blank, convert the contents to a hyperlink. The following will do the trick:

Sub URL_List()
For Each cell In Selection
If cell.Value <> "" Then
If Left(cell.Value, 7) = "http://" Then
URL = cell.Value
Else
URL = "http://" + cell.Value
End If
ActiveSheet.Hyperlinks.Add Anchor:=cell, _
Address:=URL, TextToDisplay:=cell.Value
End If
Next cell
End Sub

The macro is not foolproof; it assumes that if a cell contains anything at all it is a valid URL. What
it does is to check the cell contents and, if the contents aren't prefaced by the "http://" text, then it is
added. The hyperlink is then created based on the cell contents.
Uncovering and Removing Links
It can be frustrating to open an Excel file and be continually asked if you want to update linked
information, particularly if you are not sure what information is linked. If you want to get rid of
links in a workbook, there are several things to try.

First, choose Edit Links on the Data tab of the ribbon in Excel 2007 or choose Links from the Edit
menu in older Excel versions, if the option is available. (It will only be available if Excel recognizes
explicit links in the workbook.) From the resulting Links dialog box you cannot delete links, but
you can change the links so that they point to the current workbook. When you later save and again
open your workbook, Excel will recognize the self-referential links and delete them.

Another way you can find links is to search for either the left bracket ([) or right bracket (]) in your
workbook. The brackets are used by Excel when putting together the links to other files. For
instance, this is a link to an external file, as it would appear in a cell:

=[Book1.xls]Sheet1!$D$7

When you find links similar to the above, all you need to do is delete them. Make sure that you
search each worksheet in your workbook.

Another place to look for links is in the defined range names maintained by Excel. This is a
particularly common place for links if you are working with a workbook that contains worksheets
that were copied or moved from other locations. The defined names, rather than pointing to a cell
range in the current workbook, could be pointing to a range in a different workbook. In Excel 2007,
click the Name Manager tool on the Formulas tab of the ribbon. In older versions of Excel choose
Insert | Name | Define to display the proper dialog box. Then step through each defined name,
examining the address to which it refers. Delete or change any that refer to other workbooks.

Another place to check is your macros. It is possible to assign macros to toolbar buttons (older
versions only) or to graphics in a worksheet. Click on any custom toolbar buttons or graphics and
see if you get an error. If you do, this is a good indication that the button or graphic is linked to a
macro contained in a different file. If you delete the button or graphic, or change the macro
assignment, the link problem should go away.

Still another possible location for wayward links is in PivotTables. When you create a PivotTable, it
can refer to data on a different worksheet in your workbook. If you later move that source
worksheet to a different workbook, your PivotTable will be linked to the external data source. The
only solution here is to delete the PivotTable, copy the source data back to the current workbook, or
move the PivotTable to the external workbook.

Finally, you should check graphs and charts. If you recently moved worksheets out of your current
workbook into another workbook, it is possible that charts and graphs remaining in your current
workbook now refer to data on a worksheet you moved to another workbook. If this is the case, you
will need to either remove the graph or chart, move it to the other workbook, or copy the source
data back into the current workbook.

Default Cell Movement when Deleting


When you select a number of cells (not entire rows or columns) and then choose to delete those
cells, there are two directions that remaining cells can move: to the left or up. If the selected cells
include fewer rows than columns, then Excel offers to move the remaining cells to the left. In all
other situations (the number of rows is greater than or equal to the number of columns), then Excel
offers to move the remaining cells up, by default.

You may not want to move the remaining cells according to Excel's assumptions; you may want to
always move the remaining cells in one particular direction. There are two ways you can go about
making this happen. The first is to simply memorize the keystrokes required to always move
remaining cells in the desired direction. If you want to always move cells left, you would use the
keystrokes Alt, H, D, D, L, Enter (Excel 2007) or Alt, E, D, L, Enter (older versions of Excel).
Similarly, if you want to move cells up, just press Alt, H, D, D, U, Enter (Excel 2007) or Alt, E, D,
U, Enter (older versions of Excel). If you memorize the keystrokes, you can enter them very
quickly and achieve the desired results.

If you are a "mouse person," you may want to create a couple of macros that achieve the desired
effect, and then assign those macros to shortcut keys that can pull them up quickly. The following
macro will delete the selected cells and shift the remaining cells to the left:

Sub DeleteShiftLeft()
Selection.Delete xlShiftToLeft
End Sub

With one small change, the macro can shift the remaining cells up:

Sub DeleteShiftUp()
Selection.Delete xlShiftUp
End Sub

The only drawback to remember about using a macro is that when you invoke any macro, Excel
clears the Undo stack. Whereas you could undo a deletion if you used the menus or keyboard, if you
use a macro, you cannot undo it or any edits you did before the deletio

Inserting the User's Name in a Cell


The way to understand who is using a particular workbook is to implement a short, one-line macro
that accesses the UserName property of the Application object. That approach is great at
determining the user name associated with the current installation of Excel. However, that may not
be the same thing as who is using the current workbook. For instance, if the workbook is shared, it
is possible that multiple people could be using it at the same time. In that case, you need a way to
determine those names, as shown here:
Function UserNames() As String
Dim Users As Variant
Dim sMsg As String
Dim iIndex As Integer

Users = ActiveWorkbook.UserStatus

For iIndex = 1 To UBound(Users, 1)


sMsg = Users(iIndex, 1) & vbLf
Next iIndex
'remove final line feed
sMsg = Left(sMsg, Len(sMsg) - 1)

UserNames = sMsg
End Function
To use the function, just enter the following formula in the cell where you want the names to
appear:

=UserNames

If you instead want to know who is using the computer currently, it is best to look beyond Office
and instead grab the name from Windows itself. In that way you can determine who is logged in to
Windows and use that as the user name. This takes an API function call declaration, but is
otherwise relatively easy:

Private Declare Function GetUserName Lib "advapi32.dll" _


Alias "GetUserNameA" (ByVal lpBuffer As String, nSize _
As Long) As Long

Function UserName2() As String


Dim strBuff As String * 100
Dim lngBuffLen As Long

lngBuffLen = 100
GetUserName strBuff, lngBuffLen
UserName2 = Left(strBuff, lngBuffLen - 1)
End Function

Choosing Direction After Enter On a Workbook Basis


When you press Enter after typing information into a cell, Excel normally saves your information
and then moves to the next cell beneath the one where you pressed Enter. You can modify this
behavior, however. In Excel 2007, do this:
1. Click the Office button and then click Excel Options. Excel displays the Excel Options
dialog box.
2. At the left of the dialog box click Advanced.
3. Under Editing Options, make sure that the checkbox for "After pressing Enter, move
selection" is checked (it should be by default).
4. Using the Direction drop-down list, change the direction as desired. Changing the direction
affects how Excel behaves in all workbooks.

In Excel 2003 or earlier, do the following:

1. Choose Options from the Tools menu.


2. Click on the Edit tab
3. Adjust the Move Cursor After Enter setting. Changing the direction affects how Excel
behaves in all workbooks.

If you have a need to vary the Enter key behavior on a workbook-by-workbook basis, you might
think you are out of luck. You can, however, use a little creative macro code to specify which
direction you want to go after Enter, and have that code run whenever a workbook is activated.

For instance, let's say that you had a particular workbook, and you always want to move the
selection up after pressing Enter. In this particular workbook, you can add the following code to the
thisWorkbook object in the VBA editor:

Option Explicit
Private Sub Workbook_WindowActivate(ByVal Wn As Excel.Window)
bMove = Application.MoveAfterReturn
lMoveDirection = Application.MoveAfterReturnDirection

Application.MoveAfterReturn = True
Application.MoveAfterReturnDirection = xlUp
End Sub

Private Sub Workbook_WindowDeactivate(ByVal Wn As Excel.Window)


Application.MoveAfterReturn = bMove
Application.MoveAfterReturnDirection = lMoveDirection
End Sub

There are two separate subroutines here. The first one runs whenever the window for the workbook
is activated. In this case, it stores the settings associated with the MoveAfterReturn and
MoveAfterReturnDirection properties into variables. (You will learn about these variables shortly.)
The macro then sets the MoveAfterReturn property to True and sets the direction to xlUp. If you
want to go a different direction by default in this particular workbook, simply use a different Excel
constant, such as xlDown, xlToLeft, or xlToRight.

The second subroutine runs whenever the workbook window is deactivated. In this case, the values
of the MoveAfterReturn and MoveAfterReturnDirection properties are reset to what they were
before the workbook was first activated.

The two variables used in these routines, lMoveDirection and bMove, need to be defined in the
declaration portion of any module. This allows the variables to be accessed from both of the above
routines.

Option Explicit
Public lMoveDirection As Long
Public bMove As Boolean

Changing Huge Numbers of Hyperlinks


Assume you have a worksheet that contains over 1,200 hyperlinks to TIFF files. (These are
hyperlinks, not regular links.) Excel hiccupped and had to shut down, so you used the AutoSaved
files to recover the previously saved file. Now all the previously working hyperlinks don't work.
The hyperlinks pointed to the images on a shared network drive, but the AutoSave changed the
hyperlinks to reference the C: drive. At first blush it might seem that you could use Excel's regular
Find and Replace feature to find the hard drive designation (as in file://c:) and replace it with a
network drive (as in file://shareddrive). The problem is that this approach only addresses part of the
problem—it only changes the displayed portion of the hyperlink, not the underlying hyperlink itself.
The only way you can get to the hyperlink itself is through the use of a macro.

Assuming that all the hyperlinks that need changing are on the same worksheet, then you can use
the following macro:

Sub FixHyperlinks()
Dim wks As Worksheet
Dim hl As Hyperlink
Dim sOld As String
Dim sNew As String

Set wks = ActiveSheet


sOld = "c:\"
sNew = "S:\Network\"
For Each hl In wks.Hyperlinks
hl.Address = Replace(hl.Address, sOld, sNew)
Next hl
End Sub

All you need to do is change the values assigned to the sOld and sNew variables.

Locking All Non-Empty Cells


You have a worksheet that has hundreds of rows and columns. Some of the cells have information
in them and some are empty. The empty cells are used for data entry. He would like a way to easily
lock all the non-empty cells in a selected range and then lock the worksheet.

This is rather easy to do manually. There is an important item to keep in mind, however: All the
cells in the worksheet are "locked," by default. In other words, you don't need to look for a way to
lock the non-empty cells; you only need to look for a way to unlock the empty ones. (There is one
exception to this, addressed shortly.)

With this in mind, you can follow these steps to get your empty cells unlocked:

1. Select the range you want to affect.


2. Press F5. Excel displays the Go To dialog box.
3. Click Special. Excel displays the Go To Special dialog box.
4. Select the Blanks radio button and click OK.
5. Press Ctrl+1. Excel displays the Format Cells dialog box.
6. Make sure the Protection tab is selected.
7. Clear the Locked check box.

That's it. You can now lock your worksheet and only those blank cells that were selected at the end
of step 5 will be accessible.

One interesting thing to note is that you don't really have to select a range in step 1. If, instead, you
select a cell within the main body of your worksheet's entries, Excel assumes that you want to
operate on the used area of your worksheet. In other words, when you get to step 5 what will be
selected are all the empty cells in the used area of you worksheet.

One more thing to be aware of is that once you set the locking status of a cell (step 8), the cell
retains that status until you specifically change it. This means that if you've previously made
changes to the locking status of the cells, it may be beneficial to explicitly lock the cells prior to
unlocking the empty ones. You can do this by following these modified steps:

1. Select the range you want to affect.


2. Press Ctrl+1. Excel displays the Format Cells dialog box.
3. Make sure the Protection tab is selected.
4. Make sure the Locked check box is selected and click OK.
5. Press F5. Excel displays the Go To dialog box.
6. Click Special. Excel displays the Go To Special dialog box.
7. Select the Blanks radio button and click OK.
8. Press Ctrl+1. Excel displays the Format Cells dialog box.
9. Make sure the Protection tab is selected.
10. Clear the Locked check box.
In this case you must perform step 1—you have to select a range to affect. Excel won't assume
which range you want to affect as in the earlier comment.

If you prefer, you can use a macro to protect your cells and your worksheet:

Sub UnlockEmptyCells()
Dim myCell As Range

Set myCell = Selection


Cells.Select
Selection.Locked = True
myCell.Select
Selection.SpecialCells(xlCellTypeBlanks).Select
Selection.Locked = False

ActiveSheet.Protect DrawingObjects:=True, _
Contents:=True, Scenarios:=True
myCell.Select
End Sub

This macro makes sure that all the cells in the worksheet are locked, then it unlocks the blank cells
in the used range, and finally it protects the worksheet.

Sharing Your Workbook


Excel allows multiple people to access a workbook at the same time, if desired. This can be very
handy when a workbook is in active use or development, and there are multiple people in your
department who all have a hand in the process. You can share a workbook in this way:
1. Load the workbook you want to share.
2. Display the Review tab of the ribbon.
3. Click the Share Workbook tool, in the Changes group. Excel displays the Share Workbook
dialog box.
4. Choose the Allow Changes check box.

This is the simplest way to share access to a workbook. There are other options available in the
Share Workbook dialog box that should be examined, however. Notice that the dialog box also lists
the users currently accessing the current workbook. It should go without saying that when you first
share a workbook, you are the only user that will be listed in the dialog box. However, if you again
display the Share Workbook dialog box at a later time (such as when you are thinking of turning
sharing off), there could easily be multiple users listed.

Notice, as well, that the Share Workbook dialog box also contains an Advanced tab. This tab is
where you can specify how changes should be handled by Excel.

The whole idea behind sharing a workbook among multiple users is that Excel tracks any changes
made and then at a later date you merge together everyone's work. The Advanced tab is where you
indicate how you want Excel to prepare for this future time. Here you can specify how changes
should be tracked, when changes should be updated, and what to do if Excel detects a conflict
between changes specified by two or more users.
Tracking Down Invalid References
If, closing a workbook, you get the message: "A formula in this worksheet contains one or more
invalid references.", tracking down those invalid references can be frustrating. There are several
places you can start to look. The first is in the formulas that are on the worksheets. (Yes, you need
to do these steps for each worksheet in the workbook.) Use the Go To Special dialog box (press F5
and choose Special) to choose to go to only the cells that contain errors. You can then use the Tab
key to move amongst any cells that Excel selects.

You could also use the Find tool to look for possible errors. Just press Ctrl+F to display the Find
tab of the Find and Replace dialog box, then search for the # character. Make sure you tell Excel to
do its searching within Formulas. Inspect anything that is found to see if it is an error or not.

You should also take a look at any named ranges defined in your workbook. Look at each name in
the Define dialog box (Insert | Name | Define), making sure that whatever is in the Refers To box
doesn't include any error indications.

These aren't all the places that there could be errors; Excel is really good at letting errors exist in
lots of places. If you need to search for errors often, you might try a macro that looks through your
formulas for any potential errors.

Sub CheckReferences()
' Check for possible missing or erroneous links in
' formulas and list possible errors in a summary sheet

Dim iSh As Integer


Dim sShName As String
Dim sht As Worksheet
Dim c, sChar As String
Dim rng As Range
Dim i As Integer, j As Integer
Dim wks As Worksheet
Dim sChr As String, addr As String
Dim sFormula As String, scVal As String
Dim lNewRow As Long
Dim vHeaders

vHeaders = Array("Sheet Name", "Cell", "Cell Value", "Formula")


'check if 'Summary' worksheet is in workbook
'and if so, delete it
With Application
.ScreenUpdating = False
.DisplayAlerts = False
.Calculation = xlCalculationManual
End With

For i = 1 To Worksheets.Count
If Worksheets(i).Name = "Summary" Then
Worksheets(i).Delete
End If
Next i

iSh = Worksheets.Count

'create a new summary sheet


Sheets.Add After:=Sheets(iSh)
Sheets(Sheets.Count).Name = "Summary"
With Sheets("Summary")
Range("A1:D1") = vHeaders
End With
lNewRow = 2

' this will not work if the sheet is protected,


' assume that sheet should not be changed; so ignore it
On Error Resume Next

For i = 1 To iSh
sShName = Worksheets(i).Name
Application.Goto Sheets(sShName).Cells(1, 1)
Set rng = Cells.SpecialCells(xlCellTypeFormulas, 23)

For Each c In rng


addr = c.Address
sFormula = c.Formula
scVal = c.Text

For j = 1 To Len(c.Formula)
sChr = Mid(c.Formula, j, 1)

If sChr = "[" Or sChr = "!" Or _


IsError(c) Then
'write values to summary sheet
With Sheets("Summary")
.Cells(lNewRow, 1) = sShName
.Cells(lNewRow, 2) = addr
.Cells(lNewRow, 3) = scVal
.Cells(lNewRow, 4) = "'" & sFormula
End With
lNewRow = lNewRow + 1
Exit For
End If
Next j
Next c
Next i

' housekeeping
With Application
.ScreenUpdating = True
.DisplayAlerts = True
.Calculation = xlCalculationAutomatic
End With

' tidy up
Sheets("Summary").Select
Columns("A:D").EntireColumn.AutoFit
Range("A1:D1").Font.Bold = True
Range("A2").Select
End Sub

This macro creates a worksheet called "Summary" that is used to list information about any errors
detected in the worksheet links.

You can also use Excel MVP Bill Manville's FindLink program, which does an amazing job of
locating information in links. You could use the add-in to search for the # character in all your links,
which should help you locate the errors. More information on FindLink can be found here:

http://www.oaltd.co.uk/MVP/

Maintaining the Active Cell


An Excel workbook can contain any number of individual worksheets. As you move around within
the various worksheets, Excel keeps track of which cell is selected in which worksheet. When you
switch to a new worksheet, Excel makes active the cell that was last active within that worksheet.
Thus, if you last selected cell F9 in the worksheet, that is the one that is selected when you display
the worksheet again, regardless of what was selected in the previous worksheet.

For some workbooks, however, you may want Excel to make the active cell in the selected
worksheet the same as the active cell in the previous worksheet. There is no setting to automatically
do this in Excel, but there are a couple of things you can try. One thing is to follow these steps:

1. Hold down the Ctrl key as you click on the tab of the worksheet you want to go to. Two
worksheet tabs should now be selected; the one with the bold name is the one that is actually
displayed on the screen.
2. Click on the tab for the worksheet you want to go to. Both tabs should still be selected, but
just the one you clicked on should have its name in bold.
3. Hold down the Ctrl key as you click on the tab of the worksheet you just left.

These steps work because you are "grouping" worksheets. When you do, Excel makes the selected
cells the same for all worksheets in the group.

Remembering to use the Ctrl-click-click-Ctrl sequence can be cumbersome, at best. It is also a


sequence that can be fraught with danger, because if you forget to do step 3, you could end up
making unintended changes on your worksheets. (While you are working with grouped worksheets,
any change you make on one sheet is similarly changed on all the sheets in the group.)

These three steps cannot be automated with macros, but you can take a different approach with a
macro to accomplish the same task. The first thing you need to do is declare a public variable
anywhere within a module of the workbook, as shown here:

Public sAddress As String

This variable, sAddress, will be used to store the current address of the active cell. In the
"ThisWorkbook" module of the workbook, add these two macros:

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, _


ByVal Target As Excel.Range)
sAddress = ActiveCell.Address
End Sub
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
On Error Resume Next
If sAddress > "" Then Sh.Range(sAddress).Select
End Sub

The first macro is run automatically by Excel any time that the selected cell changes. All it does is
retrieve the address of whatever cell is active, and then store that address in the sAddress variable.

The second macro is automatically run whenever a workbook is activated. It checks to see if there is
anything stored in sAddress. If there is, it selects whatever cell address is stored there. The error
code is necessary in case you select a sheet that doesn't use cells, such as a chart sheet.

This macro approach works great if you only want to make this navigational change in a single
workbook or two. If you prefer to make the change "system wide" (so to speak), you must be a little
more complex in your approach to the macro. In this case, you need to place your code in the
Personal.xls workbook so that it is loaded every time you start Excel. Specifically, place the
following code into a new class module of the Personal.xls workbook. This class module should be
named something descriptive, such as ClassXLApp:
Public WithEvents gobjXLApp As Excel.Application
Private mstrAddress As String

Private Sub gobjXLApp_WorkbookActivate(ByVal Wb As Excel.Workbook)


On Error Resume Next
If mstrAddress > "" Then ActiveSheet.Range(mstrAddress).Select
End Sub

Private Sub gobjXLApp_SheetActivate(ByVal Sh As Object)


On Error Resume Next
If mstrAddress > "" Then Sh.Range(mstrAddress).Select
End Sub

Private Sub gobjXLApp_SheetSelectionChange(ByVal Sh As Object, _


ByVal Target As Excel.Range)
mstrAddress = Selection.Address
End Sub

Next, open the "ThisWorkbook" module of Personal.xls and copy the following code to it:

Private mobjXLApp As New ClassXLApp

Private Sub Workbook_Open()


Set mobjXLApp.gobjXLApp = Excel.Application
End Sub

Once you save Personal.xls and restart Excel, the range in the first workbook that opens will be
selected in the next worksheet that is selected.

Excluding a Specific Add-In at Startup


When you got an add-in that needs to be used only once in a while, there is little that can be done to
disable it at start-up because no particular workbook is already open. (The add-ins are loaded before
any workbooks.) There are a couple of things you could try, however.
The first thing is that you could create your own add-in that does nothing more than ask if the large
add-in should be loaded or not. Depending on the user's response, the add-in could then be loaded
by using the following line of code:

AddIns("Big Add-in").Installed = True

Of course, you'll need to replace "Big Add-in" with the name of the actual add-in to be loaded. If
the user doesn't want the add-in loaded, just skip the line of code. In the Close event for your little
add-in you could then add a line like the following that unloads the big add-in:

AddIns("Big Add-in").Installed = False

In this way, the add-in is added only if the user says it is OK to add, and then always unloaded at
the end of your Excel session.
Another approach is to never load the large add-in, but put a routine in your Personal.xls file that
gives the user a chance to load the add-in. The following could be added to the Workbook_Open
event in Personal.xls:

Private Sub Workbook_Open()


With Application
.OnKey "{TAB}", "InstallMyAddIn"
.OnTime (Now + TimeValue("0:00:05")), "DisableTABProc"
End With
End Sub

The purpose of this macro is to give the user a period of time—in this case five seconds—to press
the Tab key so that the large add-in is loaded. The .OnKey method runs the installation routine, if
Tab is pressed, and the .OnTime routine starts a timer that runs the disable routine once the five
seconds is elapsed. Notice that this macro calls two routines; these can go in a regular module for
Personal.xls.

Sub InstallMyAddIn()
AddIns("Big Add-in").Installed = True
DisableTABProc
End Sub
Sub DisableTABProc()
Application.OnKey "{TAB}", ""
End Sub

Of course, you'll need to add some code for the Workbook_Close event of
Personal.xls, in this case to unload the add-in:

Private Sub Workbook_Close()


AddIns("Big Add-in").Installed = False
End Sub

If you prefer to not use macros, then you can always just move the big add-in from it's directory
location or rename the add-in prior to starting Excel. If Excel cannot locate the add-in, it continues
to load without loading it.

Limiting Scroll Area


When putting together a worksheet for others to use, you may want to limit the cells that the user
can access. One esoteric way to add limits is to use the following steps:
1. Right-click the sheet tab for the sheet on which you want to place a limit.
2. In the resulting Context menu, choose View Code. The VBA editor appears,
displaying the code window for the worksheet whose tab you right-clicked.
3. If the Properties window is not visible, press F4.
4. In the Properties Window, place the insertion point in the box to the right of the
Scroll Area property.
5. Enter the range in which you want navigation possible. For instance, if you want
the user to only be able to access the cells in the range A3:D15, then enter that
range.
6. Close the VBA Editor.

That's it; you can no longer move to or select cells outside the range you specified in step 5. The
range you enter must be a contiguous range; you cannot enter a non-contiguous group of cell
addresses.

Setting the Default Font Size for Comment Balloons


When you insert a comment into a worksheet cell, Excel places the user's name on the first line of
the comment balloon in bold type. The insertion point is then at the beginning of the next line, ready
for your to type. What you type is inserted, by default, in 8-point Tahoma.
If you want a larger font used for your comment, you can change the character formatting of
anything within the comment itself. Just select the text, then use the controls on the Formatting
toolbar or by choosing Comment from the Format menu.
Excel does not provide a way for you to change the default font specifications for comment
balloons, across the board. You can change them individually (as already mentioned), but not
universally within Excel. You can make a change in Windows that will affect the comment font,
however. Follow these general instructions:

1. Right-click anywhere on the desktop. Windows displays a Context menu.


2. Choose Properties. Windows displays the Display Properties dialog box.
3. Make sure the Appearance tab is selected..
4. Using the Item drop-down list, choose ToolTip.
5. Using the other controls in the dialog box, change the font specifications as desired.
6. Click OK, as necessary, to close all the open dialog boxes.

In case you didn't figure it out from these steps, the font used in the comment balloons of Excel is
determined by the ToolTip font used by Windows. Changing the ToolTip font changes the
comment balloons, but it also changes things in other applications besides Excel, as well. (Of
course, if you think the font is too small in the comment balloons, you also probably think the font
is too small everywhere else the ToolTip font is used.)
If you prefer to not change the ToolTip font, you can create an Excel macro that will step through
all the comments in a worksheet to make changes.

Sub FixComments()
Dim cmt As Comment

For Each cmt In ActiveSheet.Comments


With cmt.Shape.TextFrame.Characters.Font
.Name = "Arial"
.Size = 12
End With
Next cmt
End Sub

This macro changes the font to 12-point Arial for all comments. You could easily change the font
and font size by making a change to the appropriate two lines of the macro.

Always Open at 100% Zoom


If you work with workbooks first worked on by your colleagues, you may be frustrated by the zoom
factor applied to those workbooks by those others. For instance, if your colleague (Wanda) has a
huge monitor, it wouldn't be uncommon for her to reduce the zoom factor on Excel to 75% or even
60%. The purpose, of course, is so she isn't overpowered by things that look very large at the full
zoom factor.
The problem is that the zoom factor is saved with the workbook. Thus, when Wanda saves the
workbook and hands it off to you, when you open it, the workbook is still displayed at whatever
zoom factor Wanda last used. If you don't have the same size monitor as Wanda, then the workbook
may be almost illegible on your system.
There are only two possible solutions to this problem. First, you can simply adjust the zoom factor
once you open the workbook. There are a multitude of ways to do this, but the easiest involve the
Zoom setting on the Formatting toolbar, or using the scroll wheel on your mouse. (On some
systems you may need to hold down the Ctrl key in order for the scroll wheel to adjust the zoom
factor.)
The second workaround is to create a macro that gets saved with the workbook. The macro can run
every time the workbook is opened, and thereby set the zoom factor. (This macro should be added
to the This Workbook code window in the VBA editor.)
Private Sub Workbook_Open()
ActiveWindow.Zoom = 100
End Sub

The only problem with a macro such as this, of course, is that whenever Wanda (your colleague)
opens the workbook on her system, the zoom factor is also set and she'll get just as frustrated with
you as you were with her.
Perhaps a solution is to create a more involved macro—one that checks the current screen
resolution and then sets the zoom factor accordingly. For instance, the following macro could be
used to make the adjustments based on resolution:

Declare Function GetSystemMetrics32 Lib "user32" _


Alias "GetSystemMetrics" (ByVal nIndex As Long) As Long

Public Sub ScreenRes()


Dim lResWidth As Long
Dim lResHeight As Long
Dim sRes As String

lResWidth = GetSystemMetrics32(0)
lResHeight = GetSystemMetrics32(1)
sRes = lResWidth & "x" & lResHeight
Select Case sRes
Case Is = "800x600"
ActiveWindow.Zoom = 75
Case Is = "1024x768"
ActiveWindow.Zoom = 125
Case Else
ActiveWindow.Zoom = 100
End Select
End Sub

This routine checks the screen resolution and adjusts the window accordingly. Other resolutions and
zooms may be added easily. To make the routine run automatically, just use a Workbook_Open
event handler in the This Workbook code window to trigger the macro:

Private Sub Workbook_Open()


ScreenRes
End Sub

Error Opening Second Workbook


When you open a second Excel workbook, do you see an error message indicating that
"PERSONAL.XLS is already open?" If so, this problem has to do with how you are opening the
second workbook.
There are two ways you can open workbooks: either from within Excel or from the operating
system. Opening a workbook from within Excel is done by using the Open tool on the toolbar or by
choosing File | Open. (In Excel 2007 you click the Office button and then click the Open option.)
Opening a workbook from the operating system is done if you double-click on a workbook icon.
Every time you open a workbook from the operating system, you are starting another instance of
Excel. The error message appears only if you have a Personal.xls workbook on your system and
only if you open a second workbook using the operating system method. The first time you open a
workbook, it loads Personal.xls. The second time you open a workbook (remember—you are
actually opening another instance of Excel) the program tries to load Personal.xls again. Since it is
already open, you get the error.
The solution is to open the second workbook from within Excel, not from the operating system. Use
the method of opening a workbook appropriate within your version of Excel and you won't see the
error message.
If you must open a second instance of Excel, and you don't want the error message, find the
Personal.xls workbook using Windows' Search feature. (Do this in Windows, not in Excel.) Right-
click the file and choose Properties. In the Properties dialog box for the file, choose to make the file
Read-Only. Once the file is read-only, you no longer get the error when you open up secondary
instances of Excel. Why? Because the first instance doesn't leave the file open due to it being read-
only.
You can also bypass the error condition completely if you make one small configuration change in
Excel. Follow these steps if you are using a version of Excel prior to Excel 2007:
1. Choose Options from the Tools menu. Excel displays the Options dialog box.
2. Make sure the General tab is displayed.
3. Make sure the Ignore Other Applications check box is not selected.
4. Click OK.

If you are using Excel 2007, then you must follow these steps:
1. Click the Office button and then click Excel Options. Excel displays the Excel
Options dialog box.
2. Click Advanced at the left side of the dialog box.
3. Scroll through the options until you can see the General group.
4. Make sure the Ignore Other Applications That Use Dynamic Data Exchange
(DDE) check box is not selected.
5. Click OK.

According to Excel's help system, if the Ignore Other Applications check box is selected, then Excel
won't share DDE information with other applications. This isn't all, however—it also affects how
Excel starts when you double-click on a workbook in Windows and you already have Excel open. If
the option is cleared (as it should be), then Excel starts the new workbook in the current instance of
Excel. If it is selected (as it may be), then Excel tries to open a second instance of itself, and you
will see an error message if you have a Personal.xls file on your system.
If changing the Ignore Other Applications check box causes unforeseen problems in other ways you
use Excel, then you might also consider converting your Personal.xls file to an add-in. Add-ins are
opened in a special status, akin to read-only, and can therefore be opened by more than one instance
of Excel.
DATABASE
Importare dati dal web
Per eseguire importazioni di dati presenti sui siti web, accedere al menu Dati e scegliere Importa
Dati Esterni e, da qui, Nuova Query Web. Apparirà una finestra simile a un Browser che consentirà
di raggiungere l'indirizzo che interessa. Qui selezionare le tabelle o sezioni da importare agendo sui
tag di posizionamento rappresentati da piccole frecce che vanno spuntate una per una.

A questo punto, cliccare sul pulsante Importa e, dalla finestra che segue, indicare il punto in cui si
vuole che Excel inserisca i dati estratti. L'importazione delle sole sezioni selezionate avverrà in
pochi secondi e i contenuti verranno divisi in colonne e righe diverse a seconda di come è costruito
il sito di origine. È possibile aggiornare il contenuto della cella con un clic destro sulle celle e
scegliendo Aggiorna

Connessione da Excel ad un database access con VBA


Option Explicit
‘Aggiungere i riferimenti alle librerie DAO e Office
Public gdbCurrentDB As Database
Public objRecordset As Recordset
Public objTableDefs As TableDef
Public tname As String 'nome della tabella
Public counter As Long

‘Connessione a database
Sub DbConnect()
On Error GoTo herr
 Set gdbCurrentDB = OpenDatabase("C:\....miodatabase.mdb", True)
 Exit Sub
herr:
 Set gdbCurrentDB = Nothing
End Sub
Sub GetData()
'Connessione a tabella o query
'tname è il nome della tabella
Dim k, j, l As Long
Dim n As Variant
On Error GoTo err01
Set objRecordset = gdbCurrentDB.OpenRecordset(tname)
Exit Sub
err01:
MsgBox "impossibile recuperare i dati richiesti."
End Sub

Public Sub GetTableList(rctl As Control)


  'recupera tutte le tabelle
'rctl è un controllo tipo listbox
On Error GoTo FTLErr
  Dim i As Integer
  Dim sTmp As String
  For i = 0 To gdbCurrentDB.TableDefs.Count - 1
    sTmp = gdbCurrentDB.TableDefs(i).Name
        If (gdbCurrentDB.TableDefs(StripConnect(sTmp)).Attributes And
dbSystemObject) = 0 Then
    sTmp = gdbCurrentDB.TableDefs(i).Name
    rctl.AddItem sTmp
        End If
  Next
' se vuoi recuperare anche le queries
For i = 0 To gdbCurrentDB.QueryDefs.Count - 1
   sTmp = gdbCurrentDB.QueryDefs(i).Name
rctl.AddItem sTmp
Next
' fine recupero queries

  Exit Sub
FTLErr:
  Exit Sub
End Sub

Private Function StripConnect(rsTblName As String) As String


  If InStr(rsTblName, "->") > 0 Then
    StripConnect = Left(rsTblName, InStr(rsTblName, "->") - 2)
  Else
    StripConnect = rsTblName
  End If
End Function

Creating a Photo Catalog from a Folder of Photos


You can use Excel to create a catalog with hundreds or thousands of your photos, inserting
thumbnails to the right of the photo's description, with a hyperlink to a larger photo.

When you insert a photo into Excel, the file size of your workbook is increased by at least the file
size of the photo being inserted. Thus, to ensure that the Excel file doesn’t grow to enormous size,
you have to reduce the image file size scaling the photos outside of Excel, using photo editing
software, before they are inserted into Excel. You could then insert each thumbnail into your Excel
worksheet and your resultant workbook file size would be smaller, although still directly related to
the aggregate size of the thumbnail photos you add to the worksheet.

If you still want to insert all the photos into your worksheet, you can do so using a macro. The
following example, PhotoCatalog, can look for all the thumbnail photos and insert them into the
worksheet, along with a hyperlink to the full photo. It assumes four things: (1) your photos and
thumbnails are all JPG images, (2) the photos are in the directory c:\Photos\, (3) the thumbnails are
in the directory c:\Photos\Thumbnails\, and (4) the thumbnails have the same file names as the full-
size photos.

Sub PhotoCatalog()
Dim i As Double
Dim xPhoto As String
Dim sLocT As String
Dim sLocP As String
Dim sPattern As String

sLocT = "c:\Photos\Thumbnails\"
sLocP = "c:\Photos\"
sPattern = sLocT & "*.jpg"

Application.EnableEvents = False
Application.ScreenUpdating = False

Range("A1").Select
ActiveCell.FormulaR1C1 = "Description"
Range("B1").Select
ActiveCell.FormulaR1C1 = "Thumbnail"
Range("C1").Select
ActiveCell.FormulaR1C1 = "Hyperlink"
Range("A1:C1").Select
With Selection.Font
.Name = "Arial"
.FontStyle = "Bold"
.Size = 12
.ColorIndex = xlAutomatic
End With
With Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.Weight = xlMedium
.ColorIndex = xlAutomatic
End With

i = 1
On Error GoTo 0
xPhoto = Dir(sPattern, vbNormal)
Do While xPhoto <> ""
i = i + 1
Range("B" & i).Select
ActiveSheet.Pictures.Insert(sLocT & xPhoto).Select
With Selection.ShapeRange
.LockAspectRatio = msoTrue
.Height = 54#
.PictureFormat.Brightness = 0.5
.PictureFormat.Contrast = 0.5
.PictureFormat.ColorType = msoPictureAutomatic
End With
Range("C" & i).Select
ActiveSheet.Hyperlinks.Add Anchor:=Selection, _
Address:= sLocP & xPhoto, TextToDisplay:=xPhoto
xPhoto = Dir
Loop

Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
It can take quite a while for this macro to run, depending on the type of system you are using and
how many photos you are cataloging.
Excel Applies Scientific Notation to Imported Data
When using Excel to import data from another source, sometimes the data imported are
misinterpreted by Excel. This problem was already addressed in a different ExcelTip, relative to
working with data imported from a CSV file:

http://excel.tips.net/T002426

The same cause of the problem detailed in that tip applies here, as well: Excel is interpreting the
imported data as a number when it should be interpreting it as text. The general solution is to make
sure that the cells into which your information will be imported are formatted as text before you
actually do the import.

In most cases this will solve the problem. In some cases, however, you may need to look at the code
you are using to do your import query. For instance, you may now be using the following command
to import part numbers from your ODBC source:

SELECT part_num from ODBC.table

This simply brings the part number in from the source database without any changes; Excel then
parses the incoming data trying to figure out what type of data it is. Instead you need to change the
command in this way:

SELECT "'" + part_num AS part_num from ODBC.table

Note that this approach places an apostrophe at the beginning of the part number field as it is
imported. This doesn't stop Excel from parsing the part number, but the added apostrophe forces
Excel to treat the part number as text rather than a number.

Consolidare dati in base alla categoria


1. Impostare i dati da consolidare in ogni foglio di lavoro distinto.

Impostare i dati

o Verificare che ogni intervallo di dati sia in formato elenco (elenco: Serie di righe
contenenti dati correlati o serie di righe che viene designata come foglio dati tramite
il comando Crea elenco): ogni colonna presenta un'etichetta nella prima riga e
contiene elementi simili e l'elenco non include righe o colonne vuote.
o Inserire ciascun intervallo su un foglio di lavoro distinto. Non inserire alcun
intervallo sul foglio di lavoro in cui si prevede di inserire il consolidamento.
o Verificare che le etichette delle colonne e delle righe da combinare siano digitate in
modo identico e che presentino la stessa combinazione di lettere maiuscole e
minuscole. Le etichette Media annuale e Media ann. sono diverse e non verranno
consolidate.
o Assegnare un nome a ogni intervallo. A tale scopo, selezionare l'intero intervallo e
quindi nel gruppo Celle denominate della scheda Formule fare clic sulla freccia
accanto a Inserisci nome intervallo e digitare un nome per l'intervallo nella casella
Nome.
2. Fare clic sulla cella superiore sinistra dell'area in cui si desidera visualizzare i dati
consolidati nel foglio di lavoro master.
 Nota    Verificare che a destra e al di sotto della cella venga riservato un numero di celle
sufficiente per i dati consolidati. Il comando Consolida consente di riempire l'area nel modo
desiderato.

3. Nel gruppo Strumenti dati della scheda Dati fare clic su Consolida.
4. Nella casella Funzione selezionare la funzione di riepilogo (funzione di riepilogo: Tipo di
calcolo che si utilizza durante l'unione di dati di origine in un rapporto di tabella pivot o in
una tabella di consolidamento oppure durante l'inserimento di subtotali automatici in un
elenco o in un database. Esempi di funzioni di riepilogo sono Somma, Conteggio e Media.)
che si desidera utilizzare per il consolidamento dei dati.
5. Se il foglio di lavoro si trova in un'altra cartella di lavoro, fare clic su Sfoglia per
individuare il file e quindi fare clic su OK per chiudere la finestra di dialogo Sfoglia.

Il percorso del file viene immesso nella casella Riferimento seguito da un punto
esclamativo.

6. Digitare il nome assegnato all'intervallo e quindi fare clic su Aggiungi. Ripetere la


procedura per ogni intervallo.
7. Decidere la modalità di aggiornamento del consolidamento. Eseguire una delle operazioni
seguenti:
o Se si desidera aggiornare automaticamente la tabella di consolidamento quando
vengono modificati i dati degli intervalli di origine, selezionare la casella di controllo
Crea collegamenti con i dati originari.

 Importante   Questa casella di controllo può essere selezionata solo se il foglio di


lavoro si trova in un'altra cartella di lavoro. Dopo aver effettuato la selezione, non
sarà possibile indicare celle e intervalli diversi da includere nel consolidamento.

o Per impostare il consolidamento sull'aggiornamento manuale mediante la modifica


delle celle e degli intervalli inclusi, deselezionare la casella di controllo Crea
collegamenti con i dati originari.
8. Selezionare le caselle di controllo di Usa etichette in che indicano la posizione delle
etichette negli intervalli di origine: Riga superiore, Colonna sinistra o entrambe.

  Note  

o Le etichette che non corrispondono alle etichette presenti nelle altre aree di origine
verranno posizionate in righe o colonne distinte nel consolidamento.
o Verificare che le categorie che non si desidera consolidare presentino etichette
univoche visualizzate solo in un intervallo di origine.

Synchronizing Lists
You may have an occasion when you have two data lists that want to "line up." For instance,
column A might be a customer account number, while column B displays the customer's account
balance. In columns C and D you then paste a listing of customer payments, with column C being
the customer account number and column D being the payment amount. Both lists (A/B and C/D)
are sorted by customer account number.

Since not all customers with balances made payments, the A/B list is not in synch with the C/D list.
To get them in synch, you need to insert blank cells where needed in columns C/D (and sometimes
columns A/B) so that the customer account number in column C matches the customer account
number in column A.

If your goal is to match payments to balances, then there is a relatively easy way to do this, without
the need to insert cells in the lists. Follow these steps:

1. Insert three blank columns between the two lists. When done, you should have the account
balances in A/B, blank columns in C/D/E, and the payments in F/G.
2. Assuming the first account/balance combination is in cells A2:B2, enter the following
formula in cell C2:

=IF(ISNA(VLOOKUP(A2,F:G,2,FALSE)),0,VLOOKUP(A2,F:G,2,FALSE))
3. Copy the formula down through the rest of column C.

This formula looks in the payments columns (F/G) for any cells that match the account number in
column A. If found, then the amount of the payment is returned by the formula. If a match is not
located, then a zero value is returned.

The approach works well if you know that the payment columns contain only a single payment for
each account. If it is possible that some accounts received multiple payments, then you need to
change the formula you use in step 2:

=SUMIF(F:F, A2,G:G )

This formula, if it finds a match, adds all the payments together and returns the sum.

Of course, the example first described in this tip is just that—an example of a more pervasive
problem. You may have a need to synch lists where there is only text in the lists, or where it is more
difficult to do a lookup or you don't need to return a sum. In those instances, it may be best to look
for a third-party solution.

Working with Record Numbers


For some data tables in Excel, you may want to assign a record number to cells in a particular
column. For instance, you might want record numbers for 20 different records, ranging between 1
and 20 or between 100 and 119. It doesn't really matter to Excel what range you select. How you go
about setting up the record numbers depends on what you want to later do with them.

If you want the record numbers to be static—that is, they are always assigned to a particular record
and never change—then you should use the AutoFill feature of Excel to assign the numbers. To do
this, simply enter all your data except the record numbers. Then type in the first two or three record
numbers, select them, and drag on the AutoFill handle (the black square at the bottom-right corner
of the selection) to fill out the rest of the records.

Using this approach is fast and easy, but it does make the record numbers static. For instance, if you
delete the record that has a record number of 107, then that particular record number is gone, and
your numbers will show a gap, jumping from 106 to 108.

If you want dynamic record numbers—ones that will change as you make deletions—then you can
use a formula to calculate the record numbers. You could put the first record number in, for
instance, cell A5, and then in the next cell down you would use a formula such as =A5+1 to
calculate the new record number.

This still presents a problem, however, because if you delete a record, all the record numbers below
the one you deleted will show an error (#REF!). Why? Because you delete a cell on which the next
cell down was dependent. A better solution is to use a record number formula that is dependent on
the row in which the formula is located. For instance, let's assume your first record is in row 5. You
could use this formula to generate a range of record numbers starting with 100:

=ROW()+95

Now, if you delete a record, the remaining record numbers readjust themselves and you don't end
up with any errors.
ELENCHI, FILTRI E ORDINAMENTO
Sorting Addresses by even and odd numbers
The need is to sort a list of addresses first by street name and then by house number
with the even numbers first, in ascending order, and then the odd numbers next, in descending
order.

It’s necessary to create a column that will specify each address as odd or even. Assuming the
number portion of the address is in cell A1 and the street name is in B1, in a third column you could
enter this formula:

=IF(ISEVEN(A1),B1&"_0_"&A1,B1&"_1_"&MAX($A$1:$A$19)-A1)

Where the range for the addresses is A1:A19. This formula returns the name of the street with some
numbers that are for sorting purposes only. Once the formula has been entered for each address, the
results can be sorted in ascending order. And yet another approach is to use the following formula:

=IF(MOD(A1,2)=1,(1+RANK(A1,A:A,1))/2,(COUNT(A:A)+RANK(A1,A:A)+1)/2)

The numbers returned by this formula are not particularly important; they essentially assign a
relative order for an address based on the house number. Once copied and pasted the formula down
the column, the list must be sorted first by street name in ascending order and then by the formula in
descending order. You can also use the same MOD formula as follow for a different approach:

=MOD(A1,2)*(9999999-A1*2)+A1

This formula returns two types of numbers—big ones for odd addresses and small ones for even
addresses. Coped and pasted the formula down the column, the list must be sorted first by street
name, then by formula, both in ascending order.

Applicare il Filtro Automatico da worksheet e da VBA


All’interno del worksheet è sufficiente premere il tasto “Filtro” per imporre il filtro nella prima
cella di tutte le colonne.
Da VBA, invece, si deve scrivere:

Selection.AutoFilter Field:=11, Criteria1:="8", Criteria2:="10"

dove ovviamente Field è il campo da filtrare e Criteria# il valore o i valori da selezionare.


Successivamente si può copiare i risultati con:

Set copia = Selection.SpecialCells(xlCellTypeVisible)


copia.Copy
Range("F1").Select
ActiveCell.PasteSpecial xlPasteAll

Per rimuovere il filtro dal foglio, basta scrivere nuovamente

Selection.AutoFilter

che è in pratica lo switch della funzione


Copying the Results of Filtering
If you use the advanced filtering capabilities of Excel, you are not limited to filtering "in place."
You can also do the equivalent of a database extraction, which is a two-step process. First, the list
is filtered, and then the records that match your criteria are copied to a different area of the
worksheet.

To instruct Excel to copy the results of a filtering, follow these steps:

1. Select the area you want to filter.


2. Choose Filter from the Data menu, then choose Advanced Filter. Excel displays the
Advanced Filter dialog box with the address of your original data table already filled in, in
the List Range box. (If you are using Excel 2007, display the Advanced Filter dialog box by
displaying the Data tab of the ribbon and then, within the Sort & Filter group, clicking
Advanced Filter.)
3. Set your filtering options as desired.
4. Make sure the Copy to Another Location radio button is selected.
5. Specify a copy destination in the Copy To field.

When you specify a destination for the copy (step 5), you have three options. First, if you specify a
single cell as the destination, then Excel copies the results of the filtering, regardless of the number
of records extracted. If you are working with a large list and the results of the filtering might be
many, many rows, however, you might not want to do this. In this case, make the destination a row
selection. Excel will then only copy that many rows. Thus, if the result of the filtering was 47
records, and your destination was a selection of 12 rows, only the first 12 records are copied. The
final option is to select a range of cells. This limits the copy to the number or rows and columns
specified by the range.

Working with Record Numbers


For some data tables in Excel, you may want to assign a record number to cells in a particular
column. For instance, you might want record numbers for 20 different records, ranging between 1
and 20 or between 100 and 119. It doesn't really matter to Excel what range you select. How you go
about setting up the record numbers depends on what you want to later do with them.

If you want the record numbers to be static—that is, they are always assigned to a particular record
and never change—then you should use the AutoFill feature of Excel to assign the numbers. To do
this, simply enter all your data except the record numbers. Then type in the first two or three record
numbers, select them, and drag on the AutoFill handle (the black square at the bottom-right corner
of the selection) to fill out the rest of the records.

Using this approach is fast and easy, but it does make the record numbers static. For instance, if you
delete the record that has a record number of 107, then that particular record number is gone, and
your numbers will show a gap, jumping from 106 to 108.

If you want dynamic record numbers—ones that will change as you make deletions—then you can
use a formula to calculate the record numbers. You could put the first record number in, for
instance, cell A5, and then in the next cell down you would use a formula such as =A5+1 to
calculate the new record number.

This still presents a problem, however, because if you delete a record, all the record numbers below
the one you deleted will show an error (#REF!). Why? Because you delete a cell on which the next
cell down was dependent. A better solution is to use a record number formula that is dependent on
the row in which the formula is located. For instance, let's assume your first record is in row 5. You
could use this formula to generate a range of record numbers starting with 100:

=ROW()+95

Now, if you delete a record, the remaining record numbers readjust themselves and you don't end
up with any errors.

Reorganizing Data
When importing a data list into Excel, it is not unusual to end up with a lot of data in column A. In
fact, it is not unusual to have nothing in any of the other columns. (This all depends on the nature of
the data you are importing, of course.).As an example, the imported your data can end up occupying
rows 1 through 212 of column A. These data should occupy columns A through F, of however
many rows are necessary to hold the data. Thus, A2 needs to be moved to B1, A3 to C1, A4, to D1,
A5 to E1, A6 to F1, and then A7 to A2, A8 to B2, etc.

With the following macro, select the data you want to reorganize, and then run the macro. You are
asked how many columns you want in the reorganized data, and then the data shifting begins.

Sub CompressData()
Dim rSource As Range
Dim rTarget As Range
Dim iWriteRow As Integer
Dim iWriteCol As Integer
Dim iColCount As Integer
Dim iTargetCols As Integer
Dim J As Integer

iTargetCols = Val(InputBox("How many columns?"))


If iTargetCols > 1 Then
Set rSource = ActiveSheet.Range(ActiveWindow.Selection.Address)
If rSource.Columns.Count > 1 Then Exit Sub

iWriteRow = rSource.Row + (rSource.Cells.Count / iTargetCols)


iWriteCol = rSource.Column + iTargetCols - 1
Set rTarget = Range(Cells(rSource.Row, rSource.Column), _
Cells(iWriteRow, iWriteCol))

For J = 1 To rSource.Cells.Count
rTarget.Cells(J) = rSource.Cells(J)
If J > (rSource.Cells.Count / iTargetCols) Then _
rSource.Cells(J).Clear
Next J
End If
End Sub
The macro transfers information by defining two ranges: the source range you selected when you
ran the macro and the target range defined by the calculated size based on the number of columns
you want. The source range is represented by the rSource variable object, and the target range by
rTarget. The For ... Next loop is used to actually transfer the values.

Sorting with Graphics


If the graphics inserted in a worksheet meet a couple of simple requirements, Excel allows to sort
graphics along with the regular data in the tables.
 The graphics have to be sized so they fit completely within the cell. They cannot be taller or
wider than the cell over which you placed them.
 You should make sure that the sorting function is selecting the column in which your
graphics have been placed. You can check this by seeing if the column is selected when you
choose the Sort option from the Data menu.

If the graphics still won't sort, the properties of the graphic may have been changed to prohibit
sorting. Follow these steps:

1. Right-click on a graphic image. Excel displays a shortcut menu.


2. Choose Format Picture from the shortcut menu. Excel displays the Format Picture dialog
box.
3. Make sure the Properties tab is selected. Make sure the Don't Move or Size with Cells
option is not selected.
4. Click on OK.
5. Repeat steps 1 through 5 for all the graphics in the column.

In Excel 2007 you need to follow some different steps to change the graphic properties:

1. Right-click on a graphic image. Excel displays a shortcut menu.


2. Choose Size and Properties from the shortcut menu. Excel displays the Size and Properties
dialog box.
3. Make sure the Properties tab is selected.
4. Make sure the Move and Size with Cells option is selected.
5. Click on Close.
6. Repeat steps 1 through 5 for all the graphics in the column.

Showing Filter Criteria on a Printout


Microsoft Excel includes some great tools that help you filter large data tables to include only the
information you want displayed. In effect, the filters allow you to "slice and dice" your data until
you get just what you want.
When printing out filtered data, you might want to know what slicing and dicing was done to the
original data. There are several ways you can go about displaying your filtering criteria. One simple
way is to use the advanced filtering capabilities of Excel, which require that you set up a small
criteria table for your data. If the criteria table is made part of what you print, then you can see your
filtering criteria quite easily.

If you use AutoFilter, then you need to use a different approach. One such approach is detailed at
John Walkenbach's site:

http://j-walk.com/ss/excel/usertips/tip044.htm

This solution uses a user-defined function to return any filtering criteria in use in the current
column. The function can be used in a cell, in that column, to display the criteria. If you are using
advanced filtering, then the macro approach is a bit more complex. The following macros (there are
two of them in the listing) will examine what advanced criteria are in play, and then place the
criteria in the left portion of the header.

Sub AddFilterCriteria()
Dim strCriteria As String
strCriteria = FilterCriteria()
If strCriteria = "" Then
strCriteria = "No Filtering Criteria"
Else
strCriteria = "Filter Criteria:" & Chr(10) & strCriteria
End If

' add Criteria string to Header/Footer


With ActiveSheet.PageSetup
.LeftHeader = strCriteria
End With
End Sub

Function FilterCriteria() As String


Dim rngCriteria As Range, col As Range, cel As Range
Dim strCriteria As String, r As Integer, c As Integer
Const strCriteriaRange As String = "Criteria"

FilterCriteria = ""

On Error Resume Next


'Set Criteria-Range reference
Set rngCriteria = Range(strCriteriaRange)
If Err <> 0 Then Exit Function
On Error GoTo 0

' Create Criteria String


c = 0
For Each col In rngCriteria.Columns
c = c + 1 ' CriteriaRange Columns
r = 1 ' CriteriaRange Rows
For Each cel In col.Cells
If r = 1 Then
strCriteria = strCriteria & "Criteria" _
& c & " (" & cel.Value & ") = "
Else
strCriteria = strCriteria & "'" & cel.Value & "'"
If IsEmpty(cel.Offset(1, 0)) Then
'Add New row Char if not Last Criteria Column
If c < rngCriteria.Columns.Count Then
strCriteria = strCriteria & Chr(10)
End If
Exit For
End If
strCriteria = strCriteria & " "
End If
r = r + 1
Next cel ' next criteria row
Next col ' next criteria column

FilterCriteria = strCriteria
End Function

To use the macro, just run the AddFilterCriteria macro, after you have your advanced filtering set
up. The macro reads the criteria table and puts together the criteria into a string that is placed in the
left header.
Ordinamento di range di dimensioni non determinate
Assicurarsi che la selezione di CurrentRegion copra tutto l’intervallo. Il metodo Header identifica
se la riga superiore reca (:=xlYes) o meno (:=xlNo) le intestazioni di colonna; il valore xlGuess dà
a Excel il compito di indovinarlo.
Se il filtro è uno solo, utilizzare i metodi Key e Order, senza numero.

ActiveCell.CurrentRegion.Select
ActiveWorkbook.ActiveSheet.Sort.SortFields.Clear
ActiveWorkbook.ActiveSheet.Sort.SortFields.Add _
Key1:=Range("E:E"), Order1:=xlAscending, _
Key2:=Range(“G:G”), Order2:=xlDescending,_
DataOption:=xlSortNormal, Header:=xlYes
With ActiveWorkbook.ActiveSheet.Sort
.SetRange Selection
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With

Counting Groupings Below a Threshold


When working with some data sets, you may need to know how many groups of values in the data
set have elements that fall below a certain threshold. For example, consoder this set:
27, 22, 22, 30, 32, 18, 22, 23, 28, 39, 24, 27, 35, 25, 21

If we want to know the number of groupings where the members of those groupings were under 26,
the answer would be 4. Note that this is the groupings of consecutive values below 26, not the
number of individual values below 26. Thus, in this case, the four groupings would be shown by the
brackets in the following:

27, [22, 22], 30, 32, [18, 22, 23], 28, 39, [24], 27, 35, [25, 21]

There are actually several different ways you can approach this. The first is to use a "results
column" that essentially notes changes in threshold and sequence grouping. For instance, if you had
the above values in column A of a worksheet (starting at cell A2) and the threshold value in cell E1,
then you could use the following formula in every cell to the right of a value in column A:

=IF(A2>=$E$1,B1,IF(A1<$E$1,B1,B1+1))

The formula keeps a running sum of the groups below the threshold. The max (or last value) of
column B provides the total number of groups below the threshold. The formula checks to see
whether the value immediately to the left, in column A, is above or below the threshold. If it's
above, or if not and the previous value in column A was also below, the it doesn't increment the
running sum. Otherwise, it does increment because a new grouping is starting.

A related way of doing the count is to use this formula in column B, instead:

=IF(A2>=$E$1,0,IF(A1<$E$1,0,1))

This results in column B containing a series of 0 or 1 values. The only time that a 1 value occurs is
at the start of a series that is below the threshold. This makes it easy to sum all the values in column
B, which provides the count of groupings.
If you don't want to use the results column, you can use an array formula to figure out the count.
The following formula assumes, again, that the values to be analyzed are in column A, beginning at
A2, and that the threshold value is in cell E1. Remember, as well, that array formulas are entered by
pressing Ctrl+Shift+Enter.

=SUM(IF((A2:A16<$E$1)*((A2:A16<$E$1)*1<>((A1:A15<$E$1)*ISNUMBER(A1:A15))),1))

The formula basically does what the previous results-column formula did (determines a 0 or 1 based
on whether a below-threshold grouping is starting) and then sums those values. You can find more
about array values and how to use them in other WordTips or at the following Web pages:

http://www.emailoffice.com/excel/arrays-bobumlas.html
http://www.cpearson.com/excel/array.htm

Of course, if you do these types of comparisons a lot, you may want to develop your own user-
defined function (a macro) to figure the count of groupings for you. The following is an example of
such a function.

Function CountGroups(ByVal MyRange As Range, Threshold As Single)


Dim Cell As Range
Dim bInGroup As Boolean
Dim iCount As Integer

Application.Volatile
iCount = 0
bInGroup = False
For Each Cell In MyRange
If Application.IsNumber(Cell) Then
If Cell < Threshold Then 'Less than the threshold?
If Not bInGroup Then 'Only count if starting new group
iCount = iCount + 1
bInGroup = True 'Mark as being in group
End If
Else
bInGroup = False 'No longer in a group
End If
End If
Next
CountGroups = iCount
End Function

The function looks through each cell in a range and calculates if it is the start of a new below-
threshold group or not. You use the function by using a formula such as the following in your
worksheet:

=CountGroups(A2:A16,E1)

Filtering Columns for Unique Values


It is not unusual to acquire or develop data tables that have duplicate values in a column. If you
want to see only the unique values, without the duplicates, you want to filter your data table. Excel
makes this rather easy for must scenarios. For instance, let's say you have a data table in which you
have part numbers in column A. If you want to filter the list so you see only unique part numbers,
you can follow these steps:
1. Select one of the cells in the list of part numbers.
2. Choose Filter from the Data menu, then choose Advanced Filter. Excel displays the
Advanced Filter dialog box. (If you are using Excel 2007, display the Advanced Filter
dialog box by displaying the Data tab of the Ribbon and then, within the Sort & Filter group,
clicking Advanced Filter.)
3. I always like to choose the Copy to Another Location option.
4. In the Copy To field, specify the cell where you want the list of unique, filtered values to be
copied.
5. Make sure the Unique Records Only check box is selected and click on OK.

Excel Refuses to Put Page Breaks between Subtotal Groups


Page breaks not appearing where you expect them in your subtotaled data? The only time that this
behavior should occur is if you direct Excel (in the Page Setup options) to fit the printout to a
specific number of pages. You can check to see if this is the case in this manner:
1. Display the Page Layout tab of the ribbon.
2. Click the small icon at the lower-right corner of the Page Setup group. Excel displays the
Page Setup dialog box.
3. Make sure the Page tab is displayed.
4. Make sure the Adjust To option is selected and set to 100%.
5. Click OK.

The reason that you need to make this change is that if you have your page setup configured to fit
your printout to a specific number of pages, Excel basically ignores any page breaks in your
worksheet.

Extracting Targeted Records from a List


When working with large amounts of data, you may have a need to extract just the information that
meets the criteria you specify. This is where the filtering capabilities of Excel come in handy.
Consider the scenario where you have several thousand orders, covering customers across the
country. You may want to extract the orders that belong to customers in targeted states, so that you
can process them first. You can do this using the advanced filtering capabilities of Excel. (For these
steps, assume that the data you want to filter is in columns A through K.)
1. Make sure that every column in your data list has a label that describes what is in that
column. For instance, the column containing each customer's state could have "State" as a
label.
2. In cell N1, enter the word "State". You are setting up a criteria table in this column, and this
label informs Excel which column you want to use in matching criteria. Make this cell bold,
and underline it, if desired.
3. Starting in cell N2, enter the states you want to extract from the main data list. Enter one
state per cell in the column.
4. Select a cell somewhere within columns A through K, in your main data.
5. Display the Data tab of the ribbon.
6. Click the Advanced Filter tool in the Sort & Filter group. Excel displays the Advanced Filter
dialog box, with the address of your original data table already in the List Range box. Make
sure the Copy to Another Location option is selected.
7. Place the insertion pointer in the Criteria Range box, then select (on the worksheet) the
range of cells in column N that comprise the list of states. Make sure you include cell N1,
which is the label.
8. Place the insertion pointer in the Copy To box, then select a cell where you want the records
extracted to. You can select a cell on the same worksheet or on a different worksheet.
9. If you want to leave out any duplicate records, make sure the Unique Records Only check
box is selected.

That's it: Excel copies those records that have one of your target states to whatever location you
specified in step 9, and the original data is left unchanged.

Ordinamento con Bubble Sort


Il codice che segue è un esempio di sort con il metodo Bubble Sort. In particolare, riordina i fogli di
un worksheet secondo il numero che ne costituisce parte del nome.
scambiato = True
Do While scambiato = True
scambiato = False
For q = 1 To n
volo = Sheets(q).Name
trip = val(volo)
volo_s = Sheets(q + 1).Name
trip_s = val(volo_s)
If trip > trip_s Then
Sheets(q).Move after:=Sheets(q + 1)
scambiato = True
End If
If scambiato Then Exit For
Next q
Loop

Extracting Proper Words


This code looks into a list of “assembled letters” and extract the words that are "proper," meaning
that they are found in a spell-check dictionary.
Assuming that the column contains only words (no spaces, punctuation, or phrases), you can
manually check the list in this manner:
1. Make a copy of column A into column B. You now have two identical columns.
2. Select column B and run spell check.
3. Every time a spelling change is suggested, accept it. When done, you should have column A
as your original and column B as a spell-checked version of column A.
4. In column C, enter the formula =IF(A1=B1,B1,"") and copy the formula down. This formula
only shows a word in column C if the original word matches the spell-checked version of
the word.
5. Copy all the words in column C and use Paste Special to paste Values into another location.
You now have a list of validly spelled words.
If you need to perform the validation process regularly, you may want to use a macro to instead
create your final list. The following macro steps through the word list in column A and clears any
cells that contain words not in the dictionary. After checking all the words, it then deletes all the
cleared cells.

Sub ExtractDictionaryWords()
Dim rWords As Range
Dim rCell As Range

Application.ScreenUpdating = False
Set rWords = Range(Range("A1"), _
Range("A65536").End(xlUp))
For Each rCell In rWords
If Not Application.CheckSpelling(rCell.Value) Then
rCell.Clear
End If
Next
On Error Resume Next
rWords.SpecialCells(xlCellTypeBlanks). _
Delete (xlShiftUp)
On Error GoTo 0
Set rCell = Nothing
Set rWords = Nothing
Application.ScreenUpdating = True
End Sub

Remember—this macro is intentionally destructive in its behavior, meaning that it clears out cells.
If you have any need for the original data, you'll want to run the macro on a copy of the data, not on
your only copy.
FILES E CARTELLE
BrowseForFolder per cercare una cartella con VBA in Excel
Function GetFolderPath() As String
    Dim oShell As Object
    Set oShell = CreateObject("Shell.Application"). _
    BrowseForFolder(0, "Please select folder", 0, "c:\\")
    If Not oShell Is Nothing Then
        GetFolderPath = oShell.Items.Item.Path
    Else
        GetFolderPath = vbNullString
    End If
    Set oShell = Nothing
End Function

Autodistruggi un file aperto


Sub KillMe()
    With ThisWorkbook
        .Saved = True
        .ChangeFileAccess Mode:=xlReadOnly
        Kill .FullName
        .Close False
    End With
End Sub

FUNZIONE: verificare se una cartella esiste


Function ChkFileExists(strFileName As String) As Boolean
If Dir(strFileName) <> "" Then
ChkFileExists = True
Else
ChkFileExists = False
End If
End Function

Eliminare una cartella


Per cancellare una directory vuota è sufficiente il comando

RmDir DirName

dove DirName è il nome complete di path della directory da eliminare. Se non si usa una variabile
stringa, deve essere racchiuso tra virgolette. Se all’interno della directory ci sono file o
subdirectory, il comando fallisce restituendo un errore; se non è possibile eliminare
preventivamente tutto il contenuto, si può usare la routine che segue:
Sub RemoveDir_WithFiles()
‘Crea reference a Microsoft scripting runtime library
Dim objFSO As Object
On Error GoTo DelErr
' Attenzione: Verrà cancellata la cartella Mydir senza avvisi
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.DeleteFolder "C:\Mydir", True
XitProperly:
Set objFSO = Nothing
Exit Sub

DelErr:
MsgBox "Errore:=" & Err.Number & vbCr & Err.Description
Resume XitProperly
End Sub

Copiare una cartella e tutto il suo contenuto


Sub FSO_Copy_Folders_New_Location()
‘se necessario aggiungere il riferimento alla libreria Microsoft Scripting
Runtime
   Dim fsoObj As Scripting.FileSystemObject
   Const stSourceFolder As String = "c:\Test\excel"
   Const stTargetFolder As String = \\Destination

  Set fsoObj = New Scripting.FileSystemObject


   With fsoObj
       If .FolderExists(stTargetFolder) Then
         DeleteFolder (stTargetFolder)
      End If
      .CopyFolder Source:=stSourceFolder, Destination:=stTargetFolder,
_OverWriteFiles:=True
   End With
   MsgBox "La cartella" & stSourceFolder &" è stata copiata in" &
_stTargetFolder & ".", vbInformation
   Set fsoObj = Nothing
End Sub

Spostare una cartella e tutto il suo contenuto


Sub FSO_Move_Folders_New_Location()
   Dim fsoObj As Scripting.FileSystemObject
   Const stSourceFolder As String = "c:\Test\excel"
   Const stTargetFolder As String = "C:\Destination2"
 
   Set fsoObj = New Scripting.FileSystemObject
   With fsoObj
      If .FolderExists(stTargetFolder) Then
         .DeleteFolder (stTargetFolder)
      End If
      .CopyFolder Source:=stSourceFolder, Destination:=stTargetFolder,
OverWriteFiles:=True
     .DeleteFolder (stSourceFolder)
   End With
   MsgBox "La cartella" & stSourceFolder & _
                " spostata in" & stTargetFolder & ".", vbInformation
   Set fsoObj = Nothing
End Sub

Checking for the Existence of a File


The data stored in a worksheet can often correspond to information external to that worksheet. For
instance, you might collect data that represents filenames in a directory somewhere. If you want
Excel to check whether those collected filenames exist, it's easy to do using a simple macro.

Function FileExists1(sPath As String)


FileExists = Dir(sPath) <> ""
End Function

The routine simply returns a True or False value, based on whether the specified file exists. The
value that is passed to the function needs to include a full path and file name. For example, if the
file specification (including the path) were in cell A1, you could use the following in a cell:

=FileExists1(A1)

You may not, however, want to put the full path name into the cell. In that case, you could specify it
in the actual formula, in this way:

=FileExists1("c:\your\path\here\" & A1 & ".pdf")

Of course, you could instead specify the path in the user-defined function:

Function FileExists2(sFile As String)


sPath = "c:\your\path\here\" & sFile & ".pdf"
FileExists = Dir(sPath) <> ""
End Function

With such a function you could easily create a formula in your worksheet that would "flag" any
invoices missing from the directory:

=IF(FileExists2(A1),"","Missing Invoice")

Verifica se un file è aperto


Sub Verifica_file()
Dim Book As Workbook
Dim trovato As Boolean

myPath=” C:\Documents and Settings\A\Documenti\”


myFile="nomefile.XLS"

trovato = False
For Each Book In Workbooks
If Book.Name = myFile Then trovato = True
Next Book
If Not trovato Then Workbooks.Open Filename:=myPath & myFile
End Sub

Apertura di tutti i file di una directory


Sub Dir_OpenFile()
Dim MyPath As String, myFileName As String
MyPath = "C:\"
myFileName = Dir(MyPath, vbNormal)
Do While myFileName <> ""
    Workbooks.Open Filename:=MyPath & myFileName
    ActiveWorkbook.Close (False)
    myFileName = Dir
    Loop
End Sub

Dir restituisce il primo nome di file che corrisponde a quello specificato in MyPath. Per ottenere i
successivi nomi di file nella stessa cartella, chiamare di nuovo la funzione Dir senza alcun
argomento. Se non vengono trovati altri nomi di file corrispondenti, Dir restituirà una stringa di
lunghezza zero, dopodiché sarà necessario utilizzare di nuovo MyPath nelle successive chiamate,
altrimenti verrà generato un errore. È possibile passare a un nuovo “nome percorso” senza trovare
tutti i nomi di file che corrispondono al quello corrente. Non è possibile tuttavia chiamare la
funzione Dir in modo ricorsivo. Richiamando Dir con l'attributo vbDirectory non verranno restituite
sottodirectory in modo continuo.
 SUGGERIMENTO   Dato che i nomi di file vengono individuati senza rispettare un ordine
particolare, potrebbe essere utile salvarli in una matrice e quindi ordinarla.

Looping Over Files with Dir, Through Files, Through Directories…


The following VB code snippet is pretty easy to understand. There are three variables: strPath,
strFile and x. strPath is used to pass the initial parameter to the Dir function. This simply tells Dir
which directory to traverse. strFile is used to hold the file name as the code executes and continues
to retrieve file names. x is used simply as a counter so that the correct cell in the Excel spreadsheet
is updated with the correct filename (Dir doesn’t return files in any specific order, so you may need
to sort them afterward).

Sub LoopThruDirectory()
    
Dim strPath As String
Dim strFile As String
Dim x As Integer
    strPath = “C:\temp\datajunction\XMLOUT\”
    strFile = Dir(strPath)
        
    Do While strFile <> “”
        x = x + 1
        Sheet1.Cells(x, 1) = strFile
        strFile = Dir    ‘ Get next entry.
    Loop
    
End Sub

Combining Worksheets from Many Workbooks


Do you need to pull a particular worksheet out of a group of workbooks and combine those
worksheets into a different workbook? The following macro is simple in design; it loops through all
the currently open workbooks and for each workbook (except the workbook that contains the
macro) copy the sheet named "Sheet1" from that workbook to the workbook containing the code.

Sub CopySheets1()
Dim wkb As Workbook
Dim sWksName As String

sWksName = "Sheet1"
For Each wkb In Workbooks
If wkb.Name <> ThisWorkbook.Name Then
wkb.Worksheets(sWksName).Copy _
Before:=ThisWorkbook.Sheets(1)
End If
Next
Set wkb = Nothing
End Sub

If you want the macro to grab a different worksheet than Sheet1, simply change the value of the
sWksName variable to reflect the worksheet name desired. If you don't know what the name of the
worksheet will be, but you know the worksheet to copy will always be the second worksheet in each
workbook, then you can use this variation on the macro:

Sub CopySheets2()
Dim wkb As Workbook
Dim sWksName As String

For Each wkb In Workbooks


If wkb.Name <> ThisWorkbook.Name Then
wkb.Worksheets(2).Copy _
Before:=ThisWorkbook.Sheets(1)
End If
Next
Set wkb = Nothing
End Sub

Perhaps the biggest drawback to the approaches thus far is that all the workbooks need to be open.
This might not always be feasible. For instance, you could have a hundred different workbooks in a
folder and you need to combine a worksheet out of each of them. Opening a hundred workbooks,
while technically possible, probably isn't practical for most people. In that case you need to take a
different approach.

The following macro, CombineSheets, is interactive in nature. It asks you for several pieces of
information, and then adds worksheets to the workbook based upon your responses. It first asks for
a path to the worksheets (don't include the trailing slash) and then for a pattern to use for the
workbooks. You can specify a workbook pattern using the regular asterisk (*) and question mark (?)
wildcards. For instance, a pattern of * would match all workbooks, while a pattern of Budget20??
would return only workbooks that have "Budget20" at the beginning and any two characters after
that.

Sub CombineSheets()
Dim sPath As String
Dim sFname As String
Dim wBk As Workbook
Dim wSht As Variant

Application.EnableEvents = False
Application.ScreenUpdating = False
sPath = InputBox("Enter a full path to workbooks")
ChDir sPath
sFname = InputBox("Enter a filename pattern")
sFname = Dir(sPath & "\" & sFname & ".xl*", vbNormal)
wSht = InputBox("Enter a worksheet name to copy")
Do Until sFname = ""
Set wBk = Workbooks.Open(sFname)
Windows(sFname).Activate
Sheets(wSht).Copy Before:=ThisWorkbook.Sheets(1)
wBk.Close False
sFname = Dir()
Loop
ActiveWorkbook.Save
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub

When you run the macro you are also asked for the name of a worksheet to copy from each
matching workbook. Provide a name, and if such a worksheet exists in the workbook it is copied to
the beginning of the current workbook.
If you prefer not to create your own macro for combining worksheets, you might consider the
RDBMerge add-in created by Excel MVP Ron de Bruin. You can find it for free, here:

Renaming a File
Your macros can rename a file by using the Name command. This is a holdover from other versions
of BASIC. The syntax is:

Name OldFile As NewFile

where OldFile is the name of the old file, and NewFile is the name of the new file. Both filenames
must either be string variables or be enclosed in quotes. Both filenames can contain complete path
names, but both must be on the same disk drive. If the path names differ, then the command also
has the side benefit of moving the file from one directory to another.

Filling References to Another Workbook


When you create references to cells in other workbooks, Excel, by default, makes the references
absolute, in this manner:

='[Sales Master.xls]Sheet1'!$A$5

The presence of the dollar signs means that this is an absolute reference to the cell. Because of this,
you cannot use any of Excel's automatic fill options, such as Fill Right (Ctrl+R) or Fill Down
(Ctrl+D) or AutoFill, and get the results you expect. Instead, every cell in the filled cells will
reference the exact same cell in the external workbook.

The solution to the problem is to make a quick modification to the referencing formula before you
do the fill. If you remove the dollar signs (both of them), then the formula is now relative, and
filling will work the way you expect.

Using Drag-and-Drop to Create a Hyperlink


Excel includes a very powerful feature which allows you to use drag-and-drop editing techniques to
create a hyperlink. In order to take advantage of this feature, follow these steps:
1. Make sure you have two workbooks open: the one in which you want the hyperlink to
appear and the one that is the target of the hyperlink. Both should be visible on the screen at
the same time.
2. Select the target area. For instance, select the cell or range of cells in the target workbook
that you want to use as the target of the hyperlink.
3. Move the mouse pointer so it is over the thick box surrounding the cell or range of cells. The
mouse pointer should change to an arrow.
4. Right-click and hold down the mouse button as you drag the selection to the cell in which
the hyperlink will appear.
5. When you release the mouse button, Excel displays a Context menu.
6. Select the Create Hyperlink Here option from the Context menu. Excel immediately creates
a hyperlink in the cell.

There is a caveat to understand about these steps: The drag-and-drop approach will work only if you
are working with two instances of Excel open at the same time. If, in step 1, you simply display two
workbooks by using Arrange from the Window menu, drag-and-drop won't work. Instead, you need
to open one workbook in Excel and then open Excel a second time with the second workbook. Then
the steps will work just fine.

Aprire un file scelto dall’utente con estensione predeterminata


nomefile = Application.GetOpenFilename("File Excel (*.xls), *.xls", , _
"Apri il file")
Workbooks.Open (nomefile)

Se il file ha estensione .txt, la sintassi è:


Workbooks.OpenText Filename:=NomeFile, Origin:=xlMSDOS, StartRow:=1, _
DataType:=xlDelimited, Tab:=True, Other:=False, _
FieldInfo:=Array(Array(1, 2), Array(2, 3), Array(3, 1), Array(4, 4), _
Array(5, 7), Array(6, 5), Array(7, 8), Array(8, 6), _
TrailingMinusNumbers:=True

Il parametro Tab indica ch I campi sono separate da tabulazioni (possono essere diversi, p.es.
Comma, Semicolon, Space ecc.) mentre nei FieldInfo il primo numero indica la colonna (campo),
il secondo è l’istruzione relativa a quel campo (1 = importa, 2 = importa come testo, 3 – 8 = importa
come data [vari formati], 9 = non importare. È la costante xlColumnDataType)

Deleting a File in a Macro


The syntax is:

Kill File

where File is the full path and file name of the file to be deleted. When you delete a file in this
manner, the file is not moved to the Windows Recycle bin; instead, it is immediately deleted from
your drive. If desired, you can also use wildcard characters in the File specification. For instance, if
you wanted to delete all the files in the current directory that end in the TMP extension, you could
use a command like this:

Kill "*.tmp"

Running a Macro When a Workbook is Closed


In order to run a macro automatically when a workbook is closed, all you need to do is name the
macro Auto_Close(). Thus, the following example macro is run automatically whenever the
workbook containing it is closed:
Sub Auto_Close()
Dim intStatusState As Integer

intStatusState = Application.DisplayStatusBar
Application.DisplayStatusBar = True
Application.StatusBar = "Examining transactions."
DetermineTransactions
Application.StatusBar = "Posting transactions."
PostTransactions
Application.StatusBar = False
Application.DisplayStatusBar = intStatusState
End Sub
Searching a Workbook by Default
How to create a macro that will display the correct Find and Replace box to set searching
parameters.

Sub DoBox()
ActiveSheet.Cells.Find What:="", LookAt:=xlWhole
Application.CommandBars("Worksheet Menu Bar").FindControl( _
ID:=1849, recursive:=True).Execute
End Sub

The Find method allows you to set the different parameters in the Find and Replace dialog, and then
the CommandBars object is accessed to actually display the dialog box.

Comparing Workbooks
If the worksheets in each workbook are laid out the same, and you just want to find differences
between values in the cells of each worksheet, then you can use formulas to compare worksheets.
Try the following steps:
1. Create a new workbook called Compare.xls.
2. In cell A1 of the first worksheet in Compare.xls, enter the following formula:

=IF([WB1.xls]Sheet1!A1<>[WB2.xls]Sheet1!A1,"Different","")

Copy the formula from A1 into all the other cells that represent the range you want to compare. For
instance, if you want to compare A1:G12 in both worksheets, then you would copy the formula
from A1 into the full range of A1:G12.
These steps assume that the worksheets you want to compare are both named Sheet1, and they are
in WB1.xls and WB2.xls, respectively. If you have other sheets in WB1.xls and WB2.xls to
compare, you can use similar formulas in other sheets of Compare.xls.
When done, any cell that has the word "Different" in it represents a cell that is different in the
ranges being compared. Thus, if C7 had "Different" in it, then there is a difference between the cell
C7 of Sheet1 in WB1.xls and cell C7 of Sheet1 in WB2.xls.
If you are comparing only numeric values between the two worksheets, you could use a different
formula in step 2, above:

=[WB1.xls]Sheet1!A1-[WB2.xls]Sheet1!A1

The result is a worksheet that subtracts the values in one workbook from the other, which results in
the numeric differences.

Printing Workbook Properties


When you are putting together a workbook, Excel tracks quite a bit of information that it
collectively refers to as workbook properties. You can view the different properties maintained by
Excel by simply choosing the Properties option from the File menu.
In Word you have the option to print document properties, if you desire. There is no intrinsic way to
print workbook properties in Excel. Instead, you must resort to a macro that will place the names
and values of the properties into a worksheet. You can then print the worksheet and have your
workbook properties available in hardcopy format.
The following VBA macro is an example of a good way to copy all the workbook properties to a
worksheet that can be printed:

Public Sub WorksheetProperties()


Dim p As DocumentProperty
Dim iRow As Integer

'Built in Properties
iRow = 1
Cells(iRow, 1).Value = "Built-in Properties"
Cells(iRow, 1).Font.Bold = True
iRow = iRow + 1
Worksheets(1).Activate
For Each p In ActiveWorkbook.BuiltinDocumentProperties
On Error Resume Next
Cells(iRow, 2).Value = p.Name
'If no value then Excel causes an error so ignore!
Cells(iRow, 3).Value = p.Value
iRow = iRow + 1
Next
On Error GoTo 0

'Custom Properties
iRow = iRow + 1
Cells(iRow, 1).Value = "Custom Properties"
Cells(iRow, 1).Font.Bold = True
iRow = iRow + 1
For Each p In ActiveWorkbook.CustomDocumentProperties
On Error Resume Next
Cells(iRow, 2).Value = p.Name
Cells(iRow, 3).Value = p.Value
iRow = iRow + 1
Next
On Error GoTo 0
End Sub

Importing Huge Data Files


Excel has a limit on the number of rows you can have in a worksheet—up to 65,535 rows prior to
Excel 2007. It is very possible, however, to have a raw data file that has more than this number of
rows. If you need to import that file into Excel, then doing so can appear almost impossible without
upgrading to Excel 2007. Even in Excel 2007 you may run into the limits of your system if you try
to import a file that has hundreds of thousands of rows. There are a couple of things you can do,
however.
One possibility is to make copies of the raw text file (the one you want to import) and then cut the
size of each file down. For instance, if you have a total of 110,000 rows you need to import into
Excel, and you are operating under the 65,535-row limit, you could make two copies of the raw text
file. Delete the second half of the first text file and the first half of the second. Thus, you can import
the first file (now 55,000 rows) into one worksheet and the second file (also 55,000 rows) into the
second.
If you don't want to break up your input files, you might consider importing the file into Access.
Unlike Excel, Access has virtually no limit on the number of rows you can import. You could then
either work with the file in Access, or export portions of the file to use in Excel.
Finally, you could use a macro to import the records in the large source file. There are many ways
you can do this, but the basic idea behind any approach is to fetch each row from the source file and
place it in a new row of a worksheet. The macro must keep track of how many rows it's placed, and
switch to a new worksheet, if necessary.

Public Sub LoadFile()


Dim strLine As String
Dim I As Long
Dim J As Long
Dim iLen As Integer
Dim iSh As Integer
Dim lL As Long
Dim sDelim As String
Dim MaxSize As Long

sDelim = Chr(9)
MaxSize = 65000
I = 0
Open "C:\MyDir\MyFile.txt" For Input As #5
Do While Not EOF(5)
iSh = (I / MaxSize) + 1
lL = I Mod MaxSize
Line Input #5, strLine
If Right(strLine, 1) <> sDelim Then
strLine = Trim(strLine) & sDelim
End If
J = 0
Do While Len(strLine) > 1
iLen = InStr(strLine, sDelim)
Worksheets("Sheet" & iSh).Offset(lL, J).Value = _
Trim(Left(strLine, iLen - 1))
strLine = Trim(Right(strLine, Len(strLine) - iLen))
J = J + 1
Loop
I = I + 1
Loop
Close #5
End Sub

The macro assumes you have enough worksheets already in your workbook to contain the data, and
that they are numbered Sheet1, Sheet2, Sheet3, etc. Two variables you'll want to check in the
program are the settings of sDelim and MaxSize. The first specifies what character is used as a field
delimiter in the information that is being read. The second specifies the maximum number of rows
you want on each worksheet. (Don't set MaxSize greater than whatever your version of Excel will
allow.)
Finally, note that the macro opens the text file MyFile.txt. You'll want to change this Open
statement so that it opens the real source file you want to import.

Aprire un file usando le wildcard


Per aprire un file sapendone solo una parte del nome, bisogna innanzitutto cercarlo (con il comando
DIR) nella directory definita; una volta trovato il primo file che corrisponde al criterio, lo si può
aprire normalmente:

nomecompleto = Dir (path & nomeparziale & "* " & anno & ".xlsx", vbNormal)
Workbooks.Open Filename:=path & nomecompleto

Ovviamente al posto dell’ * si possono usare uno o più ? (ognuno dei quali sostituisce un solo
carattere), mentre prima e dopo l’ * si possono usare stringhe o variabili stringa per restringere
l’intervallo di ricerca.

Use VBA SaveAs and CheckCompatibility in Excel 2007-2010


You see a lot of old SaveAs code that does not specify the FileFormat parameter. In Excel versions
before Excel 2007, code without this parameter will not cause too many problems because Excel
will use the current FileFormat of the existing file -- and the default FileFormat for new files is a
normal workbook. But because there are so many new file formats in Excel 2007-2010, we
shouldn't use code like this that does not specify the FileFormat parameter.
In Excel 2007-2010, SaveAs requires you to provide both the FileFormat parameter and the correct
file extension. For example, in Excel 2007-2010, this will fail if the ActiveWorkbook is not
an xlsm file:
ActiveWorkbook.SaveAs "C:\ron.xlsm"

This code will always work


ActiveWorkbook.SaveAs "C:\ron.xlsm", fileformat:=52 

These are the main file formats in Excel 2007-2010:

51 = xlOpenXMLWorkbook (without macro's in 2007-2010, xlsx)


52 = xlOpenXMLWorkbookMacroEnabled (with or without macro's in 2007-2010, xlsm)
50 = xlExcel12 (Excel Binary Workbook in 2007-2010 with or without macro's, xlsb)
56 = xlExcel8 (97-2003 format in Excel 2007-2010, xls)
6  = Comma Separated Text (csv)
36 = Printer (prn)
-4158 = Tab separated text (txt)

Note: I always use the FileFormat numbers instead of the defined constants in my code so that it
will compile OK when I copy the code into an Excel 97-2003 workbook. (For example, Excel
97-2003 won't know what the xlOpenXMLWorkbookMacroEnabled constant is.)
FORMATTAZIONE (VBA)
Formattazione di caratteri all’interno di un range
Sub grassetto_corsivo()
    With Selection.Font
        .Name = "Arial"
        .FontStyle = "Grassetto Corsivo"
        .Size = 10
        .Strikethrough = False
        .Superscript = False
        .Subscript = False
        .OutlineFont = False
        .Shadow = False
        .Underline = xlUnderlineStyleNone
        .ColorIndex = xlAutomatic
    End With
End Sub

Inversione di proprietà
Sub invertire_una_proprietà()
Selection.Font.Strikethrough = Not Selection.Font.Strikethrough
End Sub

Changing Page Number Format


When you print a worksheet, you can have Excel include a variety of items in the header or footer
of the printout. One of the things you can include is the page number of the page being printed. This
page number is pretty mundane—it is the Arabic value of the page being printed, as in 1, 2, 3, etc.

Some people may long for a way to print page letters (A, B, C) instead of page numbers (1, 2, 3).
There is no intrinsic way to do this in Excel. You can, however, develop a macro that will figure out
the letter that should be associated with a page, and then use that letter in the footer. The following
macro does just that:

Sub LetterPageNums()
Dim sArr(27 * 26) As String
Dim iPages As Integer
Dim J As Integer, K As Integer

For J = 0 To 26
' Fill page letter array: "A", "B", "C", ...,"AA", "AB", etc
For K = 1 To 26
If J > 0 Then
sArr((J * 26) + K) = Chr(J + 64) & Chr(K + 64)
Else
sArr(K) = Chr(K + 64)
End If
Next K
Next J

iPages = ExecuteExcel4Macro("Get.Document(50)")
' Get count of pages in active sheet
With ActiveSheet
' Print worksheet, page by page
For J = 1 To iPages
.PageSetup.CenterFooter = sArr(J)
' Set page letter
.PrintOut From:=J, To:=J
' Print page(J)
Next J
End With
End Sub

First, the macro figures out the letter equivalent of pages numbers and puts them in an array. In this
case, up to 702 page letters are calculated, which should be more than enough for any print job. The
letters are A through Z, then AA through AZ, BA through BZ, and all the way up to ZA through
ZZ.

Then, iPages is set to the number of pages in the worksheet. Finally, each page is individually
printed, with the page letter being placed into the center footer of the worksheet. If you want the
page letter in some different place, use .LeftFooter or .RightFooter instead of the .CenterFooter
property. (You can also use .LeftHeader, .CenterHeader, and .RightHeader, if desired.)

Reversing Cell Contents


Sub Reverse()
If Not ActiveCell.HasFormula Then
sRaw = ActiveCell.Text
sNew = ""
For J = 1 To Len(sRaw)
sNew = Mid(sRaw, J, 1) + sNew
Next J
ActiveCell.Value = sNew
End If
End Sub

This macro only affects a single selected cell, and it will not make any changes to a cell that already
contains a formula.

Fare lampeggiare una cella


La macro permette di fare lampeggiare la cella attiva una volta al secondo
(prevedere una procedura per fermare il lampeggio -fs)

'======In un modulo normale


Public OrigBkgCol As Long, OrigTxtCol As Long
Public OldCell As Range

Sub InitFlash()
Set OldCell = ActiveCell
OrigBkgCol = ActiveCell.Interior.ColorIndex
OrigTxtCol = ActiveCell.Font.ColorIndex
Application.OnTime Now + TimeValue("00:00:01"), "Flash"
End Sub

Sub Flash()
If ActiveCell.Interior.ColorIndex < 0 Then
ActiveCell.Interior.ColorIndex = 1 'colore fondo nero
ActiveCell.Font.ColorIndex = 2 'colore testo bianco
Else
ActiveCell.Interior.ColorIndex = (ActiveCell.Interior.ColorIndex + 1) Mod 2
ActiveCell.Font.Color = 1
End If
Application.OnTime Now + TimeValue("00:00:01"), "Flash"
End Sub

=======Copiare nel visual basic editor, nel foglio dove desiderate fare
lampeggiare una cella
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
On Error GoTo zut
OldCell.Interior.ColorIndex = OrigBkgCol
OldCell.Font.ColorIndex = OrigTxtCol
OrigBkgCol = Target.Interior.ColorIndex
OrigTxtCol = Target.Font.ColorIndex
Set OldCell = Target

zut:
End Sub

Altra variante:

Sub Lampeggiacella()
Const Texte As String = "Flashing cell..."
Dim i As Integer
For i = 1 To 10
Cells(1, 1) = Texte
Call Flash_Sequence
Next i
End Sub

Private Sub Flash_Sequence()


Dim n As Byte, Start As Variant
For n = 1 To 10
Start = Timer
Do While Timer < Start + 1 / 100
Loop
If n Mod 5 = 0 Then Cells(1, 1) = ""
Next n
End Sub

Questa invece fa lampeggiare una cella usando la proprietà stile; è innanzitutto necessario definire
un nuovo stile (formato / stile / lampeggia / Aggiungi), quindi imporre questo stile alle celle da fare
"lampeggiare". A questo punto, inserire il codice seguente in un modulo foglio e si avvia la
procedura "lampeggio" dal luogo dove si vuole che il testo lampeggi in bianco e rosso.

Dim NextTime As Date


Sub lampeggia()
NextTime = Now + TimeValue("00:00:01")
With ActiveWorkbook.Styles("lampeggia").Font
If .ColorIndex = 2 Then .ColorIndex = 3 Else .ColorIndex = 2
End With
Application.OnTime NextTime, "lampeggia"
End Sub

Sub StopIt()
Application.OnTime NextTime, "lampeggia", schedule:=False
ActiveWorkbook.Styles("Flash").Font.ColorIndex = xlAutomatic
End Sub

Questa invece fa lampeggiare un intero range:

Private Sub Worksheet_Change(ByVal Target As Range)


If Not Intersect(Target, Range("A1:D10")) Is Nothing Then CLIGNOTE
Target.Select
End Sub
‘*******Nel modulo normale
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Sub CLIGNOTE()
[A1:D10].Find (What:=Application.WorksheetFunction.Min([A1:D10]), LookAt:=x lW
hole).Activate
memo1 = ActiveCell.Font.ColorIndex
memo2 = ActiveCell.Font.Size
For x = 1 To 5
For i = 10 To 20
ActiveCell.Font.ColorIndex = 3
ActiveCell.Font.Size = i
Sleep (5)
DoEvents
Next i
ActiveCell.Font.Size = 12
ActiveCell.Font.ColorIndex = 1
Next x
ActiveCell.Font.ColorIndex = memo1
ActiveCell.Font.Size = memo2
End Sub

Altra variante:
‘*********In codice foglio
Private Sub Worksheet_Calculate ()
If Range("B8").Value = "" Then
Blink "B10"
Else
Range(“B10”).Interior.ColorIndex = 0
End If
End Sub

Private Sub Worksheet_Change (ByVal Target As Range)


Application.RunMe.CodeName & “.Worksheets_Calculate
End Sub

‘*********In codice modulo


Sub Blink (cell As String)
If Range(cell).Interior.ColorIndex = 6 Then
Range(cell(.Interior.ColorIndex = 0
Else
Range(cell(.Interior.ColorIndex = 6
End If
Application.OnTime Now + 1 / 86400, “doagain”
End Sub
Sub DoAgain()
Application.Run Sheets(“Sheet1”).CodeName & “.Worksheet_Calculate”
End Sub

FUNZIONE: Normalized number formats


In an engineering environment, it is not unusual to need to "normalize" numbers in some manner.
For instance, you may need to show numeric values normalized to multiples of 10^3, such that 7340
is expressed as 7.34 and 73400 is expressed as 73.4.

It is possible to achieve this directly in the sheet (check the chapter “FORMATTAZIONE (WS)”,
but if you don’t want to use long formulas such as those described there, you can develop a couple
of VBA functions to do the trick. The following function, MySciNum, returns a normalized
number. Thus, you would use =MySciNum(A2) in cell B2 to get the same results as noted above:

Function MySciNum(BaseNum As Double) As Double


Select Case BaseNum
Case Is >= 1
While Abs(BaseNum) > 1000
BaseNum = BaseNum / 1000
Wend
Case 0
'Do nothing
Case Else
While Abs(BaseNum) < 1
BaseNum = BaseNum * 1000
Wend
End Select
MySciNum = BaseNum
End Function

This function only returns a number. To return the units with the appropriate metric prefix, you
would use the following function. All you need to do is pass it the cell reference and the name of a
single unit. For instance, you could use =MySciPre(A2, "foo"). The macro is as follows:

Function MySciPre(BaseNum As Double, Unit As String) As String


Dim OrigNum As Double
Dim Pref As Integer
Dim Temp As String

Pref = 0
OrigNum = BaseNum
Select Case BaseNum
Case Is >= 1
While Abs(BaseNum) > 1000
BaseNum = BaseNum / 1000
Pref = Pref + 1
Wend
Case 0
Pref = 99
Case Else
While Abs(BaseNum) < 1
BaseNum = BaseNum * 1000
Pref = Pref - 1
Wend
End Select

Select Case Pref


Case -6
Temp = "atto" & Unit
Case -5
Temp = "femto" & Unit
Case -4
Temp = "pico" & Unit
Case -3
Temp = "nano" & Unit
Case -2
Temp = "micro" & Unit
Case -1
Temp = "milli" & Unit
Case 0
Temp = Unit
Case 1
Temp = "kilo" & Unit
Case 2
Temp = "mega" & Unit
Case 3
Temp = "giga" & Unit
Case 4
Temp = "tera" & Unit
Case 5
Temp = "peta" & Unit
Case 6
Temp = "exa" & Unit
Case Else
Temp = ""
End Select

If Len(Temp) > 0 Then


Temp = LCase(Temp)
Temp = UCase(Left(Temp, 1)) & Mid(Temp, 2)
If Abs(OrigNum) <> 1 Then Temp = Temp & "s"
End If

MySciPre = Temp
End Function

FUNZIONE: Determining Font Formatting


You need to determine the font and font size applied to text in a cell. For instance, if the text in cell
A1 is in 12-pt Arial, you would like a function that can be used to return "Arial" in cell B1 and 12
in cell C1.

There is nothing built-in to Excel that will allow this formatting information to be grabbed. You
can, however, create a very simple macro that will do the trick. The following macro takes, as
arguments, a cell reference and optionally an indicator of what data you want returned.

Function FontInfo1(Rn As Range, Optional iType As Integer)


Application.Volatile
If iType = 2 Then
FontInfo1 = Rn.Font.Size
Else
FontInfo1 = Rn.Font.Name
Endif
End Function

You use the function by using a formula such as this in a cell:

=FontInfo1(A1,1)

The second parameter (in this case 1) means that you want the font name. If you change the second
parameter to 2 then the font size is returned. (Actually you could have the second parameter be
anything other than 2—or leave it off entirely—and it returns the font name.)

If you want to return both values at once, you can apply a lesser-known way of returning arrays of
information from a user-defined function. Try the following:

Function FontInfo2(c As Range) As Variant


Application.Volatile
FontInfo2 = Array(c.Font.Name, c.Font.Size)
End Function
Select two horizontally adjacent cells (such as C7:D7) and type the following formula:

=FontInfo2(A1)

Because the function returns an array, you need to terminate the formula entry by pressing
Shift+Ctrl+Enter. The font name appears in the first cell (C7) and the font size appears in the
second cell (D7).

Replacing and Converting in a Macro


When you use a macro to process data you always run the risk of making that data unusable by
Excel. This is especially true if you are using the macro to convert from one numbering system to
another. The reason for this behavior is that Excel VBA "speaks" American, and some actions done
using a recorded macro don't work as expected due to that fact. Because American Excel expects
the decimal separator to be a period, interpreting a "number" in VBA with another separator (such
as a comma) will cause Excel to consider the value to be text.

The workaround is not to use find and replace, but to use a different trick. Consider the following
short macro:

Sub ConvertNumbers()
Dim oConRange As Range
Set oConRange = ActiveSheet.UsedRange.Cells.SpecialCells(xlConstants)
oConRange.Value = oConRange.Value
End Sub

This macro defines a range that consists of all the cells that contain constants. Then, it sets the value
of each cell in the range equal to itself. In the process of doing this, Excel re-evaluates the contents
of each cell and converts it to the appropriate numeric value. In other words, numbers that contain
decimal points are converted to numbers that contain decimal commas.

There are other ways you can process the cells using a macro, but the above procedure seems to
work the best and the quickest.

Random Width and Height Changes


It is unclear what might be causing this problem, but there are a few things you can check. If the
workbook is stored on a network, where it can be accessed by other people, it could be that the
change is occurring while someone else has the workbook open. In addition, if the workbook is
opened on different machines, it could be that the other machines on which it is opened may be
affecting the workbook, provided they have different screen resolutions or different printer fonts
installed.

Being unsure as to the cause, it may be that the best solution is to create a macro that runs
automatically when the workbook opens. This macro could go through the worksheets and set the
column widths and row heights to what you need The following macro will perform these steps:

Private Sub Workbook_Open()


Dim wSheet As Worksheet

For Each wSheet In Worksheets


' Change to the columns you need
Columns("A:M").Select
' Change to the width you need
Selection.ColumnWidth = 12

' Change to the rows you need


Rows("1:15").Select
' Change to the height you need
Selection.RowHeight = 13
Next wSheet
End Sub
FORMATTAZIONE (WS)
Normalized number formats
In an engineering environment, it is not unusual to need to "normalize" numbers in some manner.
For instance, you may need to show numeric values normalized to multiples of 10^3, such that 7340
is expressed as 7.34 and 73400 is expressed as 73.4.

It is possible in Excel to use a custom number format to express information in scientific notation
that will normalize the display of a number to a multiple of 10^3. To do this, you would follow
these steps:

1. Select the cells you want formatted.


2. Display the Format Cells dialog box. (In Excel 2007 display the Home tab of the ribbon and
click the small icon at the lower-right corner of the Number group. In older versions of
Excel choose Cells from the Format menu.)
3. Make sure the Number tab is selected.
4. In the list of format categories, choose Custom.
5. In the Type box, enter ##0.0E+0 as your format (This provides only one number to the right
of the decimal place. If you want more, increase the number of zeros after the decimal
place.), and click on OK.

Now, when you enter a number such as 7340 into the cell, Excel displays it as 7.3E+3. Because of
the way the cell format was entered, the portion after the E will always be a multiple of 3.

This is fine and good, but what if you want just the 7.3 in the cell, and then a metric prefix with a
unit in an adjoining cell, such as kilograms? This is a bit more complex, but it can be done using
formulas. For instance, let's assume you have your original number in cell A2, you wanted the
normalized number in cell B2, and the metic prefix and unit name in cell C2. All you would need to
do is enter the following formula in cell B2:

=IF(OR(A2>=1,A2<=-1),SIGN(A2)*(ABS(A2)/(10^(3*INT(LOG(ABS(A2))/3)))),
IF(A2=0,0,SIGN(A2)*(ABS(A2)*10^(-3*INT(LOG(ABS(A2))/3)))))

Assuming the units you are working with are an imaginary unit called a foo, in cell C2 you would
use a different formula, as follows:

=IF(OR(A2>=1, A2<=-1),CHOOSE(INT(LOG(ABS(A2))/3)+1, "Foos", "Kilofoos",


"Megafoos", "Gigafoos", "Terafoos", "Petafoos", "Exafoos"),
IF(A2=0,"",CHOOSE(INT(-LOG(ABS(A2))/3)+1, "Millifoos", "Microfoos",
"Nanofoos", "Picofoos", "Femtofoos", "Attofoos")))

These formulas may seem a bit long, and they are. However, they will work for any number
between approximately -9.99999E-18 to 9.99999E+20. For instance, if you put the number .000125
in cell A2, then cell B2 will contain 125 and cell C2 would contain Millifoos.

Check the chapter “FORMATTAZIONE (VBA)” for macros that achieve the same results.
Superscripts in Custom Formats
When working in Excel, you can easily format text so that it contains superscripts, subscripts, or
whatever other formatting tricks you want. You use the Format Cells dialog box (Ctrl+Shift+F) to
make these font modifications. This dialog box is not available when you are defining custom
formats, however. (You can't use the tools on the Font tab of the Format Cells dialog box while you
are defining a custom format on the Number tab of the Format Cells dialog box.) What if you want
to place a superscript in your custom formats?

The answer is to use some of the special font characters available to Windows users. Using these
characters you can easily insert superscripted numbers, as long as they are the numbers 0, 1, 2, or 3.
Simply use the following shortcuts, where you hold down the Alt key as you type the numbers on
the numeric keypad:

Superscript   Shortcut
0   Alt+0186
1   Alt+0185
2   Alt+0178
3   Alt+0179

These shortcuts work if you are using the Arial font in your worksheet, which is the default. If you
are using some other font, the character codes to create the superscripted numbers may be different.
In that case, you will need to use the Windows Character Map accessory to figure out what shortcut
keys to use to get the results you want. (On my Windows XP system, I can access the Character
Map accessory by choosing Start | All Programs | Accessories | System Tools | Character Map. It
may differ on your version of Windows. You may also need to install the Character Map using
Windows Setup program if you cannot find it on your system.) When using the Character Map, you
can select a symbol and see in the lower-right corner of the program window what the numeric
keypad shortcut key is for the character.

Flashing a cell using Conditional Formatting


Highlight all cells requiring input with a Fill colour. Then add two format conditions one for
completion, the other to highlight errors.

Condition 1
Cell value is: equal to =""""""
Select a Pattern then click OK
Repeat to highlight errors

Condition 2
Formula is  ISERROR(G9)
Apply a different pattern & click OK

Shading a Cell Until Something is Entered


When creating a worksheet in which information must be entered into specific cells, you may find it
helpful to shade the cells if they are blank, but have the shading removed if something is entered
into the cell. You can easily accomplish this task by using the conditional formatting feature in
Excel.
Follow these steps if you are using Excel 2007:

1. Select the cells to which the conditional formatting should apply.


2. Display the Home tab of the ribbon.
3. Click the Conditional Formatting tool in the Styles group. Excel displays a list of
conditional formatting options.
4. Choose New Rule. Excel displays the New Formatting Rule dialog box.
5. In the list of rule types, select Use a Formula to Determine which Cells to Format. In the
formula area, enter the following formula, replacing A1 with the address of the active cell
selected in step 1:

=ISBLANK(A1)
6. Click Format to display the Format Cells dialog box.
7. Click the Fill tab.
8. Select the color you want used for shading the cell if it is blank.
9. Click OK to dismiss the Format Cells dialog box. The shading color you selected in step 9
should now appear in the preview area for the rule.

Follow these steps, instead, if you are using an older version of Excel:

1. Select the cell or cells that you want shaded if they are empty.
2. Choose Conditional Formatting from the Format menu. Excel displays the Conditional
Formatting dialog box.
3. Use the Condition drop-down to choose Formula Is.
4. In the formula area, to the right of the drop-down list used in step 3, enter the following
formula, replacing A1 with the address of the active cell selected in step 1:

=ISBLANK(A1)
5. Click Format to display the Format Cells dialog box.
6. Click the Patterns tab.
7. Select the color you want used for shading the cell if it is blank.
8. Click OK to dismiss the Format Cells dialog box. The shading color you selected in step 7
should now appear in the preview area for the condition.

All the empty cells among those selected in step 1 should now appear shaded. When you enter
something into one of the shaded cells, the shading should disappear.

Shading Rows with Conditional Formatting


One way to use the conditional formatting feature is to cause Excel to shade every other row in a
table. This is great when you have a particularly wide table, and you want to make it a bit easier to
read on printouts. Simply follow these steps if you are using Excel 2007:
1. Select the table whose alternate rows you want to shade.
2. Make sure the Home tab of the ribbon is displayed.
3. Click the Conditional Formatting tool. Excel displays a series of choices.
4. Click New Rule. Excel displays the New Formatting Rule dialog box.
5. In the Select a Rule Type area at the top of the dialog box, choose Use a Formula to
Determine Which Cells to Format.
6. In the formula space, enter the following formula:

=MOD(ROW(),2)=0
7. Click on the Format button. Excel displays the Format Cells dialog box.
8. Make sure the Fill tab is selected.
9. Select the color you want used for the row shading, then click on OK twice.

Those familiar with Excel 2007 may wonder why anyone would use conditional formatting to
highlight different rows of a table when you can use the table formatting feature (available in the
Styles group of the Home tab of the ribbon) to accomplish the same thing. The reason is simple—
using conditional formatting provides much more flexibility in the formatting applied as well as in
the interval of the rows being shaded.

If you are using an older version of Excel then there is no style to provide alternate-row formatting,
so you must use conditional formatting. Follow these steps:

1. Select the table whose alternate rows you want to shade.


2. Choose Conditional Formatting from the Format menu. Excel displays the Conditional
Formatting dialog box.
3. Using the pull-down condition, select Formula Is. Excel changes the dialog box controls to
reflect your choice.
4. In the formula box, enter the following:

=MOD(ROW(),2)=0
5. Click on the Format button. Excel displays the Format Cells dialog box.
6. Make sure the Patterns tab is selected.
7. Select the color you want used for the row shading, then click on OK twice.

Conditionally Formatting Non-Integers


In a list of numeric values, some are integers; some have digits to the right of the decimal. You
would like to use conditional formatting to highlight those values that have digits to the right of the
decimal point. There are a large number of ways that this can be done, and a number of different
approaches. I won't go into how to define a conditional format here; such information has already
been covered in other issues of ExcelTips. Instead I'll focus on the condition itself and how you
should select the condition to test.

If you know that the list will only contain numeric values, then you could use any number of
formulas to determine whether the value is a non-integer. These are just a few that can be used if
you specify that the condition contains a formula:

 =MOD(A1,1)>0
 =A1<>INT(A1)
 =A1-INT(A1)>0
 =NOT(A1=INT(A1))
 =(A1-TRUNC(A1))>0
 =ABS(A1)-INT(ABS(A1))>0
 =IF(FIND(".",A1),1,0)
 =(A1-(ROUNDDOWN(A1,0))>0)

The various formulas (and there could be many more listed) basically check to see if the unaltered
value in the cell is equal to a version that makes sure there is nothing to the right of the decimal.

If you prefer (for some reason) to not rely upon a formula to define your condition, then you can
choose "cell value is greater than" and set the condition as ROUNDDOWN(A1,0). You could also
use "not equal to" in the condition and you could change ROUNDDOWN to ROUNDUP. Either
way, you are testing to determine whether a rounded version of the number (rounded to the nearest
integer) is equal to the original value or not.

You should note that any integer value in your list is formatted with decimal places, then such a
value won't be "caught" by these conditional formats. For instance, if a cell contains the value 41
but the cell is formatted to display the value as 41.00, that value won't be "marked" by the
conditional format as having something to the right of the decimal point. The reason is that the
value really is an integer; it is just the display that adds the decimal point and two zeros.

Highlighting Cells Containing Specific Text


You can use the conditional formatting feature in Excel to help draw attention to cells that contain
specific text in which you are interested. For instance, if you have a range of cells and you want to
know which ones contain the letters "shawn," then you can do the following in versions of Excel
prior to Excel 2007:
1. Select the range of cells.
2. Choose Conditional Formatting from the Format menu. Excel displays the Conditional
Formatting dialog box.
3. In the drop-down Condition list, choose "Formula Is".
4. In the formula box, enter the following formula. (Make sure you replace A1 with the cell
address of the cell in the upper-left corner of the range selected in step 1.)

=NOT(ISERR(SEARCH("Shaw",A1)))
5. Click on Format. Excel displays the Format Cells dialog box.
6. Using the controls in the dialog box, specify a format that you want used for those cells that
contain the specified text. For instance, you may want bold text in a red typeface.

If you are using Excel 2007 then you should follow these steps, instead:

1. Select the range of cells.


2. With the Home tab of the ribbon displayed, click the Conditional Formatting option in the
Styles group. Excel displays a palette of options related to conditional formatting.
3. Choose Highlight Cells Rules and then choose More Rules from the resulting submenu.
Excel displays the New Formatting Rule dialog box.
4. In the Select a Rule Type area at the top of the dialog box, choose Use a Formula to
Determine Which Cells to Format.
5. In the Format Values Where This Formula Is True box, enter the following formula. (Make
sure you replace A1 with the cell address of the cell in the upper-left corner of the range
selected in step 1.)

=NOT(ISERR(SEARCH("Shaw",A1)))
6. Click Format to display the Format Cells dialog box.
7. Using the controls in the dialog box, specify a format that you want used for those cells that
contain the specified text. For instance, you may want bold text in a red typeface.
8. Click OK to dismiss the Format Cells dialog box. The formatting you specified in step 7
should now appear in the preview area for the rule.

You can make this approach even more general-purpose in nature by specifying a cell that contains
what you want to search for. For instance, if you type "Shaw" in cell F7, then you could replace the
formula in step 4 or step 5 with the following:

=NOT(ISERR(SEARCH($F$7,A1)))
Now, you can search for something different just by changing the characters in cell F7.

Formatting Currency
If you want to format currency values so what would normally appear as $10,000.00 would appear
as $10.000,00 (the difference between the US method and the European method of displaying
figures of displaying figures, there are three ways to accomplish a switch.

The easiest method is to simply change the Regional Settings in Windows. The exact way you do
this depends on the version of Windows you are using, but in general there is a choice in the
Windows Control Panel that allows you to specify regional settings. All you need to do is modify
those settings to match the numeric display format desired. The change will affect not only the
display of numbers in Excel, but in other Windows-compliant programs, as well.

The second method is to use a formula to handle the numeric display. This has the drawback of
converting the numeric value to text, but it could be easily done. For instance, let's assume that you
have the formatted numeric value $10,000.00 in cell A1. The following formula, in a different cell,
would display the text $10.000,00:

=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(TEXT
(A1,"$#,##0.00"),".","^"),",","."),"^",",")

This formula first converts the number to an initial currency format in text. Then the SUBSTITUTE
function is used to first change "." to "^" ("^" is used as a temporary placeholder), and then change
"," to ".", and finally "^" to ",".

The final method has the advantage of leaving your numbers as numbers, instead relying on a
custom format. All you need to do is to multiply your values by 100 and then use the following
custom format:

#"."###"."###","##

The format allows any number up to 9.999.999,00 to be used. If you deal with numbers that have
more than two decimal places, you will need to adjust your custom format accordingly, or adjust the
value being displayed so that it has nothing to the right of the decimal point after it is multiplied by
100.
FORMULE E FUNZIONI (VBA)
FUNZIONE: Making VLOOKUP Case Sensitive
The VLOOKUP function, like other lookup functions in Excel, is not case sensitive. In other words,
it doesn't matter whether the characters being evaluated are upper- or lower-case. You can find
ways to achieve this in chapter “FORMULE E FUNZIONI (WS)”.

In some instances you might want to create your own user-defined function that will do the lookup
for you. The following is an example of such a macro:

Function CaseVLook(compare_value, table_array As Range, _


Optional col_index As Integer = 1)
Dim c As Range
Dim rngColumn1 As Range

Application.Volatile

Set rngColumn1 = table_array.Columns(1)


CaseVLook = "Not Found"

'Loop first column


For Each c In rngColumn1.Cells
If c.Value = compare_value Then
CaseVLook = c.Offset(0, col_index - 1).Value
Exit For
End If
Next c
End Function

To use the macro, simply call the function with the value you want to find (say cell C1), the range
whose first column should be searched (such as A:B), and optionally the offset of the column within
that range, as here:

=CaseVLook(C1,A:B,2)

A few additional approaches can be found at the following Knowledge Base article:

http://support.microsoft.com/?kbid=214264

Cancellare il contenuto di una cella fino ad una sequenza data di caratteri


One way to do this is to use a formula (check the chapter “FORMULE E FUNZIONI (WS)”)

If you prefer a macro-based solution you could use a routine like the following. It examines all the
cells that are currently selected and then deletes everything before the =XX= sequence.

Sub DeleteToSequence()
Dim rCell As Range
Dim sSeq As String
Dim x As Long

sSeq = "=XX="
For Each rCell In Selection
x = InStr(rCell.Value, sSeq)
If x > 0 Then
rCell.Value = Mid(rCell, x)
End If
Next

Set rCell = Nothing


End Sub

You should be aware that this macro can cause some errors, particularly when what you are
searching for begins with an equal sign (as in =XX=). When a string beginning with an equal sign is
stuffed back into the cell, you'll get a #NAME? error because Excel tries to parse the cell as if it
contains a formula.

If you want to delete everything up through the character sequence, use this line in the middle of the
routine:

rCell.Value = Mid(rCell, x + Len(sSeq))

FormulaR1C1 con riferimenti variabili


Esempio con SOMMA:

Selection.FormulaR1C1 = "= SUM(RC[" & coli & "]:RC[-1])"

Ricordare comunque che le formule inserite nelle celle via VBA seguono la sintassi anglosassone,
quindi p.es. il punto e virgola diventa virgola.

FUNZIONE: Conversione di riferimento R1C1 in A1


Function Conv_R1C1_A1 (r As Integer, c As Integer) As String
Dim str As String
If c>26 Then str = Chr$ (Asc (“A”) + Int ( c / 26 ) – 1 )
str = str & Chr$ ( Asc (“A”) + c - ( Int (c / 26 ) * 26 – 1 )
Conv_R1C1_A1 = str + CStr ( r )
End Function

Funzione “CONTA.SE” in FormulaR1C1


Esempio di funzione CONTA.SE:
ActiveCell.FormulaR1C1 = _

"=COUNTIF(R[-" & maxrighe + i & "]C:R[-2]C, ""=" & tipo & """)"

Funzione “SOMMA.PIU.SE” in FormulaR1C1


Esempio di funzione SOMMA.PIU.SE:
ActiveCell.FormulaR1C1 = _

= "=SUMIFS(R[-" & maxrighe + i & "]C:R[-2]C,R[-" & maxrighe + i & "] _

C[-" & sposta - lin & "]:R[-2]C[-" & sposta - lin & "], ""=" & tipo & """)"
FORMULE E FUNZIONI (WS)
Usare il NOME del FOGLIO
A volte si ha la necessità di usare il percorso dove è salvato il file in uso all'interno del foglio stesso.
Per visualizzare il percorso, basta scrivere:

=CELLA("nomefile")

Il risultato sarà qualcosa come:


D:\Documents and Settings\Nomeutente\Documenti\Excel\[Elenco TIPS.xls]Foglio1

Foglio1 è il nome del foglio e si trova dopo il simbolo "]". Attraverso la combinazione delle
formule STRINGA.ESTRAI(), DESTRA(), LUNGHEZZA(), TROVA() e CELLA() possiamo
estrarre il solo nome del foglio:

=STRINGA.ESTRAI(CELLA("FILENAME");TROVA("]";CELLA("FILENAME"))+1;255)

CELLA() restituisce il percorso completo del file con nome del file e foglio attivo.
STRINGA.ESTRAI() permette di identificare, all'interno del risultato di CELLA il nome del file
che si trova subito dopo la parentesi quadra "]" che contiene il nome del file. TROVA() serve per
indicare la posizione da cui iniziare a estrarre.

Evitare Errori di ARROTONDAMENTO nelle Formule


Summary: Some formulas just don't give the results you expect. Sometimes this is due to the way
that Excel handles rounding. Here's what you can do to avoid rounding errors in your formulas. The
problem has to do with binary arithmetic and the fact that Excel rounds information. Behind the
scenes, Excel always rounds information to 15 digits.

=0.28*100-INT(0.28*100)=0

When Excel first calculates this, the precedence followed by Excel calculates it in this manner:

=(0.28*100-INT(0.28*100))=0

Note the extra set of parentheses. The result of everything to the left of that final equal sign is
3.55E-15, which means that you end up with this (longhand) formula:

=0.00000000000000355=0

This is obviously not true, which is why you get the value False returned. There are several ways to
"fix" this situation. In this case, perhaps the easiest is to simply change your formula to remove the
need to compare to zero:

=0.28*100=INT(0.28*100)

This formula returns True, as you would expect. This may not work for all your needs, however. So,
a better rule of thumb to avoid problems is to never rely on Excel's rounding. You do this by
implementing your own explicit rounding, as shown with these formulas:

=INT(0.28*100)-INT(0.28*100)=0
=ROUND(0.28*100,0)-INT(0.28*100)=0
=ROUND(0.28*100,5)-ROUND(0.28*100,5)=0

Note that you are, in these instances, not allowing Excel to perform calculations to its full precision
since that can cause some unexpected results when you are comparing to a specific value, such as
zero. Instead, you are forcing Excel to round the values—all the values you are working with—to
whatever level of precision you need for your comparison.
Another approach is to not do the comparison to an exact value, like zero. Instead, allow for some
"fudge factor" in the comparison, which allows for rounding issues. For instance, you may
determine that you only care if the comparison is accurate to one one-hundredth of whatever units
you are assuming. In that case, the original formula could be modified in this manner:

=0.28*100-INT(0.28*100)<0.01

This returns True, as one would expect.

CERCA.VERT
CERCA.VERT consente di cercare un dato in un campo di una matrice/tabella e ottenere un dato
contenuto in un altro campo della stessa tabella. P. es., in una tabella che contiene "Cognome,
Nome, Numero di telefono" è possibile cercare "Mario Rossi" e ottenere il numero di telefono che
sarà indicato nella 3a colonna a destra del cognome.

Se questa tabella fosse contenuta nell'intervallo A1:C5, la formula sarebbe:

=CERCA.VERT("Mario Rossi";A1:C5;3;FALSO)

In pratica, la formula cerca "Mario Rossi" nel range A1:C5 e, quando trova questa stringa, riporta il
contenuto della cella che si trova 3 colonne più a destra.

La sintassi di CERCA.VERT prevede quattro argomenti:


1) elemento da cercare: può essere un testo, un numero o un riferimento a una cella contenente
l'elemento da ricercare: questo sarà cercato solo nella prima colonna a sinistra dell'elenco definito
nel secondo argomento
2) indirizzo della tabella dove sono contenuti i dati: è la tabella contenente i dati da ricercare
3) numero della colonna dalla quale prelevare il dato ricercato: rappresenta la n-esima colonna a
destra della colonna di ricerca, il cui contenuto costituirà il risultato cercato.
4) approssimazione vero/falso: se impostato su VERO, permette a Excel di approssimare le ricerche
e di riportare sempre un risultato. Se cercassimo Pippo e nell'elenco non ci fosse, verrebbe riportato
il dato alfabeticamente precedente a Pippo (per esempio, "Pappo"... se esiste!)

Uno dei presupposti fondamentali per far funzionare bene la funzione CERCA.VERT è che le
tabelle siano ordinate: se questa condizione non è vera, il calcolo è molto più lento.
L'ordinamento diventa obbligatorio quando si usa l'approssimazione. Di solito, l'approssimazione
(4° argomento di CERCA.VERT) porta più danni che benefici. Esiste tuttavia un caso in cui
conviene impostare il quarto argomento su VERO: se la tabella di riferimento rappresenta dei range
ordinati di dati, questa funzionalità torna utile. Immaginiamo di voler classificare un'età in base a 4
livelli: fino a 15 "bambino", da 16 a 35 "adulto", da 36 a 50 "high spender", da 51 in su "fuori
target". Anziché usare un SE, possiamo seguire questa strada:

 nel range A1:A4 scriviamo 0, 16, 36, 51 e nella colonna accanto le categorie relative
 nella cella D1 inseriremo un numero e faremo in modo che la cella E1 riporti la categoria
 in E1 dovremo scrivere
=CERCA.VERT(D1;A1:B4;2;VERO).

Qualunque numero da 0 a infinito sarà classificato senza problemi

Making VLOOKUP Case Sensitive


The VLOOKUP function, like other lookup functions in Excel, is not case sensitive. In other words,
it doesn't matter whether the characters being evaluated are upper- or lower-case. If you need the
function to pay attention to character case, then you will need to devise a workaround. The
techniques in this tip are a great place to start. The VLOOKUP function doesn't have a way to check
for the case of information; it is case insensitive. There are several ways you can work around this
shortcoming, however. One way is to use the CODE function to create an intermediate column that
can be searched by VLOOKUP. Assuming that your original data is in column B, you could put the
following formula in cell A1 and copy it down the column:

=CODE(LEFT(B1,1))&"."&CODE(MID(B1,2,1))&"."&CODE(RIGHT(B1,1))

This formula looks at the first three characters of whatever is in cell B1 and converts those
characters to decimal character codes separated by periods. Thus, if A1 contained "ABC" then B1
would contain "65.66.67". Assuming that the value you want to locate is in cell C1, you could use
the following as your VLOOKUP formula:

=VLOOKUP(CODE(LEFT(C1,1))&"."&CODE(MID(C1,2,1))&"."&
CODE(MID(C1,3,1)), A:B,2,)

Another approach is to use the EXACT function to determine the location of what you are looking
for. This approach doesn't use VLOOKUP at all, instead relying on the INDEX function. The
formula assumes that the cells you want to compare are in column A and what you want to return is
the corresponding cell in column B.

=IF(MIN(IF(EXACT(C1,$A$1:$A$100),ROW($A$1:$A$100)))=0,NA(),
INDEX($B$1:$B$100,MIN(IF(EXACT(C1,$A$1:$A$100),ROW($A$1:$A$100)))))

This formula needs to be entered as an array formula (Shift+Ctrl+Enter). The first part of the
formula (the first instance of EXACT) compares C1 (what you are looking for) to each value in the
range A1:A100. Since this is an array formula, you end up with, in this case, 100 True/False values
depending on whether there is an exact match or not. If there is a match, then the first ROW
function returns the row of the match and the INDEX function is used to grab the value from
column B in that row.

In some instances you might want to create your own user-defined function that will do the lookup
for you. Check the chapter “FORMULE E FUNZIONI (WS)” for it.

Using VLOOKUP to Access Information to the Left


One of the most useful function in Excel is VLOOKUP. One thing it won't do, however, is allow
you to lookup information to the left of the index column. If a negative index number is used with
VLOOKUP, then Excel returns an error value (#VALUE) instead of looking up the information you
want.

Obviously, since VLOOKUP can only use positive index values, one solution is to reorganize your
data so that it all appears to the right of your index column. Such an approach may not be feasible
for many people, however. (The layout of the worksheet may be "cast in stone" by your company,
for instance.)

There are a couple of ways you can approach this problem—ways that do not involve the use of
VLOOKUP at all. The first is to simply use the LOOKUP function. Assuming that the value you
want to look up is in cell A1, the range in which you want to find it is in the range G12:G145, and
the "to the left stuff" is in F12:F145, you could use this formula:

=LOOKUP(A1,G12:G145,F12:F145)

This approach works just fine, provided that you are working with data in the lookup range
(G12:G145) that is sorted. If your data is not sorted, then you should skip this approach and instead
use the section approach, involving a combination of INDEX and MATCH. Assuming your data is
in the exact same ranges, you could use this:

=INDEX(F12:F145,MATCH(A1,G12:G145,0))

Calcolare la MEDIA dei numeri, ignorando i valori 0


Utilizzare le funzioni MEDIA e SE per eseguire questa operazione.

=MEDIA(SE(A2:A7<>0; A2:A7;""))

 NOTA    La formula dell'esempio deve essere immessa come formula in forma di matrice (formula
in forma di matrice: Formula che esegue più calcoli su uno o più insiemi di valori e quindi
restituisce un unico risultato o più risultati. Le formule in forma di matrice sono racchiuse tra
parentesi graffe { } e vengono immesse premendo CTRL+MAIUSC+INVIO.). Una volta copiato
l'esempio in un foglio di lavoro vuoto, selezionare la cella A9. Premere F2, quindi
CTRL+MAIUSC+INVIO. Se la formula non viene immessa come formula in forma di matrice,
verrà restituito l'errore #VALORE!.

Criteri multipli per CONTA.SE e SOMMA.SE (emula xxxx.PIU.SE di Excel


2007)
Questa formula conta i valori nell’intervallo C4:C11 solo se maggiori di zero e minori del valore
indicato nella cella F13

=CONTA.SE($C$4:$C$11;"<=" & F13) - CONTA.SE($C$4:$C$11;"<=0")

Quest’altra invece SOMMA le celle nell’intervallo E3:E9 per le quali sono soddisfatte
ENTRAMBE le condizioni relative alle celle corrispondenti negli intervalli B3:B9 e D3:D9.
ATTENZIONE! Questa funzione richiede che tutti gli intervalli abbiano la stessa dimensione!
=MATR.SOMMA.PRODOTTO((B3:B9=B12)*(D3:D9=D12)*E3:E9)

Counting with Two Criteria


When you use Excel as a simple database program to store individual records, you may have a need
to count the records which meet two criteria. CountIf doesn't permit two conditions to be checked in
calculating a solution. There are, however, a couple of solutions you can use, without the need of
adding additional columns or intermediate calculations.
The first (and perhaps simplest) solution is to use the SUMPRODUCT worksheet function. This
function allows you to count or sum data from a column, row, or array with as many criteria as you
want. The basic syntax is as follows:

=SUMPRODUCT( (CONDITION1) * (CONDITION2) * (CONDITION3) * (DATACELLS) )

In a particular instance, you could put the formula together like this:

=SUMPRODUCT((B2:B101="X")*(C2:C101>0))

What this does is provide two different conditions that are checked. First, the cells in column B are
checked to see if they equal "X", then the corresponding cells in column C are checked to see if
they are equal to 0. Both conditions return either True (1) or False (0). These results are then
multiplied by each other, resulting in either 1 or 0. The SUMPRODUCT function then adds them
together, resulting in a cumulative count.

Another solution is to create an array formula that will do the calculation for you. Array formulas
are different than regular formulas, in that they work on a number of cells, iterating through them to
produce a result. Consider the following formula:

=(B2="X")*(C2>0)

This returns a single value, either 1 or 0. The formula uses the same basic logic described in the
earlier explanation of the SUMPRODUCT solution. The two logical comparisons return 1 or 0,
which are multiplied by each other, resulting in 1 or 0 as an answer. Now, consider the following
formula:

=SUM((B2:B101="X")*(C2:C101>0))

This now looks very much like the earlier SUMPRODUCT formula, but it will not work properly as
a straight formula. This is because SUM is not designed to work in an iterative fashion on an range
of cells. If you enter this formula as an array formula (press Shift+Ctrl+Enter to enter it), then
Excel understands you want to work through each of the ranges, in turn, to figure the final sum,
which is a count of records that meet the stated criteria.

The different ways you can use array formulas is quite a broad topic. For more information on array
formulas refer to the following Web site:

http://www.cpearson.com/excel/ArrayFormulas.aspx

A third option is to use the database worksheet functions to return a count. Using these, you set up a
"criteria table" in your worksheet, and then the function uses the criteria to analyze the records. The
following steps assume that the column labels for the three columns are RecNum, Location, and
Cost:

1. Find a few empty cells, either on the same worksheet as your records or on a different
worksheet. (For the sake of this example, I assume you are using columns J and K.)
2. In cell J1, enter the word Location.
3. In cell K1, enter the word Cost.
4. In cell J2, enter X.
5. In cell K2, enter >0. You have now entered your criteria table in cells J1:K2.
6. Select cells J1:K2.
7. Display the Define Name dialog box or, in Excel 2007, the New Name dialog box. versions
of Excel prior to Excel 2007 choose Name from the Insert menu, then choose Define. In
Excel 2007 display the Formulas tab of the ribbon and then click on Define Name in the
Defined Names group.
8. Enter the name Criteria, then click OK.
9. In the cell where you want a count of records meeting your criteria, enter the following:

=DCOUNT(B1:C101,2,Criteria)

Notice that the first argument used with DCOUNT is the second and third columns of your records
list. This argument also includes the column labels, which are necessary so that DCOUNT can
locate the proper criteria matches from the criteria table (third argument).

Usare le SOMME 3D
Per sommare i dati dello stesso intervallo di un numero imprecisato di fogli si può usare la Somma
Tridimensionale: la sintassi si basa sulla vicinanza dei fogli di lavoro e permette di specificare, per
un certo intervallo di celle, da quale foglio a quale foglio eseguire il calcolo. Per esempio:

=SOMMA(Foglio1:Foglio5!A1:A6)

somma tutti gli intervalli A1:A6 nei fogli che si trovano tra Foglio1 e Foglio5 compresi.

Se inseriamo o copiamo dei fogli tra Foglio1 e Foglio5 nella cartella di lavoro, tutti i valori
contenuti nelle celle da A1 ad A6 dei fogli aggiunti verranno inclusi nel calcolo.
I fogli 1 e 5 sono metaforicamente dei contenitori: se eliminiamo o spostiamo dei fogli in essi
contenuti, i rispettivi valori verranno rimossi dal calcolo.
Se spostiamo uno di questi fogli, il calcolo verrà adattato ai fogli tra essi compresi

AUTORIEMPIMENTO con i Giorni della Settimana


The AutoFill feature of Excel is very handy, allowing you to automatically fill cells with all sorts of
information, based on the content of cells you select. For instance, if you fill two cells with the
words "Monday" and "Tuesday," and then select those cells, you can drag the AutoFill handle to fill
other cells with other days of the week.

What if you want to only fill cells with the workdays, Monday through Friday? This is easy to do if
you make one small change in how you use the AutoFill handle. Instead of clicking and dragging it
with the left mouse button, click and drag with the right mouse button.

When you release the button, a Context menu appears. Two of the options on the menu are "Fill
Days" and "Fill Weekdays." If you choose Fill Days, then the range is filled with the names of the
seven days of the week, the same as if you had used the left mouse button to do the AutoFill. The
other option, Fill Weekdays, fills the range with the names of only the five days of the week,
Monday through Friday.

Noting Inactivity within a Timeframe


Summary: There are many times when you are creating a worksheet that you need to analyze dates
within that worksheet. Once such instance may be to figure out whether a certain date is outside
some timeframe that you specify. This tip takes a look at how to accomplish such an analysis feat.
(This tip works with Microsoft Excel 97, Excel 2000, Excel 2002, Excel 2003, and Excel 2007.)

Graham is a lawyer with several hundred clients. He uses Excel to record time spent on client
projects. In column A he notes the client, column B contains the date, column C the start time, and
column D the end time. Graham would like to easily identify if he has not done anything for a client
for more than three months from the current date.

There are a few ways you can accomplish this task, depending upon the characteristics of the data
you are working with. If each client has a single line in the data table then you can use a simple
conditional formatting rule to highlight those clients with record dates (column B) older than 90
days. Here's the formula you would use in the rule:

=(TODAY()-B2)>=90

The formula subtracts the date in B2 from today's date, which provides a number of days between
the two dates. If it is greater than or equal to 90, then the formula is true and your conditional
format is applied.

This approach can be used if there are multiple records for each client, but it may not provide as
clear-cut of an indicator as you might like. If you sort the records by client name, you can easily see
which records from each client are over 90 days old. But you would then need to visually make a
determination whether all the records for a given client are over 90 days so you can determine if
you need to close out their account or not.

It may be better to use a different conditional formatting rule if your data table has multiple records
per client. The following formula can be applied to all the clients in column A:

=AND(COUNTIF($A$2:$A2,$A2)=COUNTIF($A:$A,$A2),(TODAY()-B2)>=90)
It checks to see if there date is outside the desired 90 days, but it only does so if the current record is
the last record for the client in the list.

Pasting Leading Zeroes


Some data requires leading zeroes. The first example that comes to mind is ZIP Codes, in which
some have leading zeroes. There are other examples, as well. For instance, you may have a chart of
accounts in which general ledger account numbers start with leading zeroes.

When you paste information into Excel, it normally tries to "parse" the data and put it in a format
that it can work with. When you paste data that have leading zeroes, and the data could reasonably
be construed as numbers, then Excel strips the leading zeroes from what you are pasting. For
instance, 0012387 become a number value, 12387.

What if you want to retain the leading zeroes? All you need to do is make sure that the target cells
—the ones that will receive the data being pasted—are formatted as text. Follow these steps:

1. Select the cells that will hold the data you are going to paste.
2. Display the Format Cells dialog box. (In Excel 2007 display the Home tab of the ribbon and
click the small icon at the lower-right corner of the Number group. In older versions of
Excel choose Cells from the Format menu.)
3. Make sure the Number tab is selected.
4. In the Category list, choose Text, then click on OK.
Whatever you now paste into the formatted cells is assumed to be text, and Excel will leave your
leading zeroes exactly as you expect them.

Easily Changing Links


Excel allows you to link information from one worksheet to another, or even from one workbook to
another. Many people do this very thing when they use one worksheet as a "summary" overview of
information contained in other worksheets.

If you organize your data in this manner, you may be wondering about the best way to change links
within your worksheet. When you link information, Excel keeps track within the link of the source
of the link. For instance, the following link refers to cell C7 in the MayData worksheet of the
2008Budget.xls workbook:

=+[2008Budget.xls]MayData!$C$7

If you have quite a few of these links in a worksheet, it can be bothersome to update each link when
you change the source workbook or worksheet used by the links. You could, of course, use Excel's
find and replace feature to make the desired changes, but there is an easier way: Use the INDIRECT
and ADDRESS functions.

For instance, let's assume that you have cells containing a workbook name (J1), a worksheet name
(J2), a numeric row number (J3), and a column number (J4). In this instance, you could use the
following formula to specify a link:

=INDIRECT(ADDRESS(J3,J4,1,TRUE,"["&J1&"]"&J2))

The result is that Excel will calculate an indirect address based on the contents of the cells. If you
want to change the place from which Excel pulls information, all you need to do is change the
contents of cells J1 through J4 so they represent the desired source.

You should note that you will need to have the source workbooks open in order to use this
approach. If they are not open, Excel won't be able to update the information as desired.

Nomi delle celle


Una delle funzionalità più interessanti e utili di Excel è l'uso dei nomi. Il loro utilizzo permette di
trasformare una formula come

=A$5*Foglio2!$c$27*(1-F25)*(1+G27) in

=A$5*cambio*(1-sconto)*(1+IVA)

migliorando sensibilmente la leggibilità/comprensibilità della formula.

Il nome è una variabile che fa riferimento a una singola cella o a un intervallo di celle: questa
variabile può essere usata all'interno di una formula in qualsiasi punto della cartella. Per esempio, se
nel foglio1, cella A1 abbiamo definito il nome IVA, potremo usare questo nome anche nel foglio2
in un calcolo che lo richiama (per esempio =A2*IVA) e Excel restituirà il risultato corretto.

Per usare i nomi abbiamo due strade, una più lenta, ma più precisa ed una più veloce. Iniziamo dalla
prima:
 Selezionare la cella o il range cui attribuire il nome.
 Selezionare la finestra Definisci dal menu Inserisci/Nome
 Inserire il nome usando la sintassi corretta: non potremo mai usare riferimenti a celle (per
esempio A1 o N25) e non è consentito quasi nessun simbolo a eccezione del simbolo
underscore ("_")

La seconda modalità consiste nel selezionare la cella o le celle e digitare il nome stesso nella
Casella del Nome, cioè il menu a tendina che appare in alto a sinistra accanto alla barra della
formula. Questo metodo ha il limite di non consentire nessun tipo di editing: per modificare un
nome, dovremo cancellarlo (entrando nella finestra Definisci dal menu Inserisci/Nome,
selezionando il nome da cancellare e facendo clic su Elimina) e inserirlo di nuovo.
La casella Riferito a consente di modificare le celle a cui il nome fa riferimento.

All'interno del sottomenu Nome del menu Inserisci vi sono alcune opzioni utili per la gestione dei
nomi. Fra queste vanno senz'altro citate:
 Incolla:scegliendo Incolla e poi Incolla Elenco, Excel incollerà (sovrascrivendo la/e cella/e
in cui vi siete posizionati) un elenco dei nomi utilizzati in tutta la cartella e la loro relativa
posizione
 Applica: consente di trasformare i riferimenti delle formule utilizzate nella cartella di lavoro
nei nomi creati successivamente

Copiare formule mantenendo i riferimenti relativi


Per copiare un range di celle mantenendo inalterati i riferimenti relativi delle formule è possibile
usare il tool Sostituisci del menu Modifica (o Ctrl + Maiusc + S).
E’ necessario sostituire il simbolo "=", p.es. con il simbolo di paragrafo "§" (nella tastiera italiana
Maiusc + ù), in modo che la formula venga interpretata come un testo”"inanimato”.
Le formule, trasformate in testo, potranno essere copiate ed incollate senza temere che Excel
interpreti a modo suo la formula. Al termine possiamo sostituire nuovamente il simbolo "§" con
"=". Fare attenzione a non usare un simbolo usato all'interno della formula e verificare la correttezza
dei riferimenti.

Incrementing References by Multiples when Copying Formulas


Here's how to put together a formula that will increment properly when copied: e.g., if the cell B1
contains the formula =SUM(A1:A7), the result of the copy in cell B2 would be the range
incremented by 7 rows, =SUM(A8:A14), in cell B3 would contain =SUM(A15:A21), etc. The
“normal” copy increments the range by 1. The reason is simple: most of the times incrementing by
1 makes sense from a formulaic perspective…and Excel can't read the mind.

The solution is to use the function INDIRECT, that uses the value in the string as if it was a real
range:

=SUM(INDIRECT("A" & (ROW()-1)*7+1 & ":A" & (ROW()-1)*7+7))

If you put this formula into cell B1, it works because it takes a look at the row number (returned by
the ROW function) of the row in which the formula is contained. Since it is in row 1, then the
formula is evaluated in this manner by Excel:

=SUM(INDIRECT("A" & (ROW()-1)*7+1 & ":A" & (ROW()-1)*7+7))


=SUM(INDIRECT("A" & (1-1)*7+1 & ":A" & (1-1)*7+7))
=SUM(INDIRECT("A" & 0*7+1 & ":A" & 0*7+7))
=SUM(INDIRECT("A" & 0+1 & ":A" & 0+7))
=SUM(INDIRECT("A" & 1 & ":A" & 7))
=SUM(INDIRECT("A1:A7"))
=SUM(A1:A7)

Another way is to use the function OFFSET:

=SUM(OFFSET(A1,((ROW()-1)*6),0):OFFSET(A7,((ROW()-1)*6),0))

A shorter approach that uses OFFSET is as follows:

=SUM(OFFSET($A$1,ROW()*7-7,0,7,1))

Regardless of the approach, you can probably tell that the idea is to come up with a formula that
uses the row in which the formula appears in order to construct the range that you really want. Each
of the examples so far assumes that you are starting in cell B1. If you want to start in cell B2, then
you'll need to modify the formulas to account for whatever row you are starting on. To give you just
an idea of how this works, if you were starting in cell B2, instead, the three formulas presented in
this tip would be modified in the following ways:

=SUM(INDIRECT("A" & (ROW()-2)*7+2 & ":A" & (ROW()-2)*7+8))


=SUM(OFFSET(A2,((ROW()-2)*6),0):OFFSET(A8,((ROW()-2)*6),0))
=SUM(OFFSET($A$2,(ROW()-1)*7-7,0,7,1))

Start at a different location, and you'll need to make further modifications to the formula you choose
to use.

Random Numbers in a Range


Excel provides a power function that allows you to easily return a random integer number within a
range. For instance, you can use the RANDBETWEEN function to return a random integer number
between 50 and 99, or between –25 and 0. The syntax for the function is as follows:

=RANDBETWEEN(lower, upper)

All you need to do is provide the lower and upper values. If the first number you provide is actually
higher than the second number, then RANDBETWEEN returns a #NUM! error.

For Excel 2007 users the RANDBETWEEN function is built into the program. If you are using an
earlier version of Excel, RANDBETWEEN is a part of the Analysis Toolpak. If you get an error
when you try to use the function, you can make sure the toolpak is loaded in this manner:

1. Choose Add-Ins from the Tools menu. Excel displays the Add-Ins dialog box.
2. Make sure the Analysis Toolpak check box is selected and click on OK.

Recuperare il Tipo di oggetto selezionato


Sub System_TypeOfSelection()
MsgBox "E’ selezionato un: " & TypeName(Selection) & ".", vbInformation
End Sub
Determining a Value of a Cell
You already know that a cell in a worksheet can contain any number of different items: numbers,
dates, formulas, and so on. There may be times when you want to determine the underlying value in
a cell, without regard to the way the cell is formatted. For this need, Excel provides the N worksheet
function. For instance, let's assume that cell F17 contains a date. If you use = N(F17) as your
formula, the value returned by the formula is the underlying serial number used for the date.

Besides returning date serial numbers, the N worksheet function returns a number if the referenced
value or cell can be resolved to a number, a 1 if the value or cell can be resolved to the logical value
True, and a 0 for anything else. The following provides a few examples of how the N worksheet
function works:

Value in F17   Returned by = N(F17)


3/11/99   36230
37.14   37.14
TRUE   1
Quarter 1   0
5:40   0.236111

Cancellare il contenuto di una cella fino ad una sequenza data di caratteri


One way to do this is to use a formula. For instance, the following formula will evaluate whatever is
in cell A1 and simply return everything up to the =XX= characters. If the characters are not found
in the cell, then the entire cell is returned:

=RIGHT(A1,IF(ISERROR(FIND("=XX=",A1,1)),LEN(A1),LEN(A1)-FIND("=XX=",A1,1)+1))

If you want, instead, to not return the first occurrence of =XX=, all you need to do is change the +1
near the end of the formula to -3.

If you prefer a macro-based solution, check the chapter “FORMULE E FUNZIONI (VBA)”

Rounding to Even and Odd Values


Excel includes two functions that allow you to quickly round a number up to the next highest even
or odd integer values. For instance, suppose you have the value 26.3 in cell A7, and the following in
cell A9:

=EVEN(A7)

The value returned by this function is 28, which is the next highest even integer value. The
following function will return a value of 27, which is the next highest odd value:

=ODD(A7)

If the value in A7 were negative, then both the ODD and EVEN functions will return values that are
further away from zero than the value used as an argument (but they are still odd and even).
Excluding Values from Averaging
In many sporting events, the average score for an athlete is determined by throwing out the highest
score and the lowest score, and then averaging the rest. You may have a need to do similar types of
averages. For instance, you may be a teacher and need to exclude the two lowest assignment scores
before calculating an average.
To perform this type of averaging, all you need to remember is that an average is calculated by
summing all the values in a range, and then dividing that sum by the number of items in that range.
The SUM function easily provides the sum, and the COUNT function can be used to find out the
number of items in the range. How to exclude the two lowest values in the range? You can use the
SMALL function. Consider the following formula, which assumes you want to find an adjusted
average of the range A10:A14:

=(SUM(A10:A14)-SMALL(A10:A14,1)-SMALL(A10:A14,2))/(COUNT(A10:A14)-2)

The SMALL function is used to determine the two lowest values in the range, and these are
subtracted from the overall sum of the range. The resulting value is then divided by the COUNT of
values in the range. Note, as well, that the COUNT value is decreased by 2 to compensate for the
fact you are ignoring the two lowest values.
Another way to calculate the same average is to use an array formula. The following one does the
trick:

=AVERAGE(IF(A10:A14>SMALL(A10:A14,2),A10:A14))

Since this is an array formula, you need to enter it by pressing Ctrl+Shift+Enter instead of just
pressing Enter. This formula still relies on the use of the SMALL function, but it also uses the
actual AVERAGE function to return a result. Since this is an array formula, it examines each of the
values in the array (the range) and only considers them for use in the average if they are larger than
the second smallest value in the array.
While the array formula is shorter than the longer regular formula, there is one caveat to keep in
mind: The array formula will produce an undesired result if there is a two-way "tie" in the second-
lowest value in the range, or a three-way tie in the lowest value. For instance, if the values being
averaged are 3, 2, 10, 3, and 7, then the array formula will produce an average of 8.5. Why?
Because only the values 10 and 7 are above the second-lowest value, and the average of those two
is 8.5. If you use the longer formula, first presented above, then the average returned is 6.666667,
which is the average of 10, 3, and 7.
If you try these formulas and they don't work, you should check to make sure that you have the
Analysis ToolPak installed. The SMALL function is a part of that ToolPak.

Pasting Without Updating References


As you are working on a worksheet, copying and moving information from one place to another,
you may wonder if there is a way to copy or move a selection without Excel changing all the
references within the selection. The answer, of course, is that it depends. (Don't you just love that
about Excel?) Let's take a look at how you can both copy and move selections in Excel.
If you are copying a selection, then Excel will update all relative references within the selection
when you paste it. The solution, of course, is to make sure that all the references within the
selection are absolute before doing the copy and paste. Making the changes to the formulas by hand
is tedious. You can use the following macro to convert all the formulas in the selection to their
absolute equivalent:

Sub ConvertToAbsolute()
Dim c As Variant
Application.ScreenUpdating = False
For Each c In Selection
c.Value = Application.ConvertFormula(c.Formula, _
xlA1, , xlAbsolute)
Next c
Application.ScreenUpdating = True
End Sub

Once this macro is run, you can copy and paste the selection without Excel doing any updating to
references. Once the pasting is done, you can change the references in the selection (and in the
original range, if it still exists) by selecting the range and applying this macro:

Sub ConvertToRelative()
Dim c As Variant
Application.ScreenUpdating = False
For Each c In Selection
c.Value = Application.ConvertFormula(c.Formula, _
xlA1, , xlRelative, c)
Next c
Application.ScreenUpdating = True
End Sub

This macro will change all formulas in the selected range to their relative equivalent. Remember
that this will affect all formulas—which means that if the formulas in the range contained both
relative and absolute references, when this macro is done, they will all be relative.
If you are moving a selection, then Excel does not update cell references in the move. You can
move either by selecting the range and using the keyboard (pressing Ctrl+X to cut and
then Ctrl+V to paste the selection) or the mouse (dragging the selection to a new location). In either
case, Excel leaves the references in the selection exactly the same—relative or not—without
updating.
So far I have discussed what Excel does with the references in the selection being copied or moved.
What about references to the information in the selection? If you are copying, then Excel leaves
references pointing to the original range. If you are moving a selection, then Excel updates
references to that selection, regardless of whether they are relative or absolute. If you don't want the
information updated during a move, then the solution is to make a copy of the range and then delete
the original.

Finding the Directory Name


If you have a need to find out the directory in which your workbook is saved, you may be tempted
to use a macro to figure out the answer. While this is a valid approach (and relatively easy), some
people are intimidated by macros or don't want to use them within the workbooks. The following
worksheet formula will return the directory in which the workbook is stored:
=LEFT(CELL("Filename",$A$1),FIND("[",CELL("Filename",$A$1))-1)

If you use this formula in a workbook that is brand new—one that has yet to be saved—then it will
return a #VALUE! error. This happens because the filename has not yet been set, and the LEFT
function cannot return a portion of something that is not there. To avoid the error, simply encase the
formula in an IF function, as follows:
=IF(CELL("Filename",$A$1)>"",LEFT(CELL("Filename",

$A$1),FIND("[",CELL("Filename",$A$1))-1),"")

In this variation the CELL function is used to determine if the filename has been set. If it has, then
the directory name is extracted and returned. If not, then an empty string is returned.
GRAFICI E IMMAGINI
Copiare un’immagine da un foglio ad un altro
Questa macro copia l’immagine etichettata con “Picture 2” dal foglio 1 del book attivo al foglio 1
del book “tipo”, con l’angolo superiore sinistro nello spigolo della cella A1:
Sheets(1).Select

Worksheets(1).Shapes("Picture 2").Copy

Windows(tipo).Activate
Sheets(1).Select
Range("A1").PasteSpecial

Per conoscere le etichette delle immagini di un book si può ricorrere a questa:


Public Sub mm()

Dim sp As Shape

For Each sp In Worksheets("Foglio2").Shapes


MsgBox sp.Name
Next

End Sub

Automatically Updating Charts for Additional Data


Excel shines at turning your data into charts—graphical representations of your data. You can easily
create a chart based on a range of data in a worksheet. Normally, if you add additional data to your
range, you will need to once again create the chart or at best change the range of cells on which the
chart is based.

If you get tired of modifying charts to refer to new data ranges, there are a couple of shortcuts you
can try out. The first shortcut works fine if you simply need to "fine tune" the range used in a chart.
(This approach only works if the chart is on object on the same worksheet that contains the data on
which the chart is based.) Follow these steps:

1. Enter any new data to the table on which the chart is based.
2. Select all the cells that you just entered.
3. Click anywhere on the selection border around the cells. (Don't click on the fill handle.)
4. Drag the selection toward the chart and drop it on the chart.

That's it - Excel incorporates the new data right into the existing chart, slick as a whistle.

Another approach is to add new data to the range not at the end, but somewhere within the range.
For instance, you may have some data that represents a time period, such as 11/1 through 11/13, and
you create a chart based on those dates. If you add new data to the end of the range (after 11/13),
then Excel doesn't know you want those items added to the chart.

Instead, insert some blank rows somewhere within the data range; it doesn't matter where, as long
as the record for 11/13 is below the added rows. You can then add the new data in the new rows,
and the chart is automatically updated to include the data.
One drawback to this approach, of course, is that the inserted data will be out of order when
compared to the overall structure of the data table. It is interesting to note that for some types of
data—such as those based on dates—Excel will automatically sort the data by date as it presents it
in the chart, but not in the data table itself. You can always use Excel's sort feature to reorder the
data in the table, all without affecting what is presented in the chart.

Still another approach is to create a "dynamic range." This approach works well if the data range
you are charting is the only data on the worksheet. Follow these steps:

1. Create your data table as you normally would. (To keep things simple, we'll assume that you
are creating a two-column data table, in columns A and B, that you then want to chart.)
2. Create your chart, as desired.
3. With the worksheet visible, display either the Define Name or New Name dialog box
depending on your version of Excel. In Excel 2007 display the Formulas tab of the ribbon
and, in the Defined Names group, click Define Name. In older versions of Excel click on
Insert | Name | Define.
4. In the Names in Workbook or Name field (depending on your version of Excel) enter a
name that will refer to the data in column A.
5. In the Refers To field, enter the following formula. You should change the sheet name and
beginning cell (in this case $A$2), as necessary. If you change the beginning cell, you
should also change the final part of the formula (-1) to be one less than the row number of
the beginning cell. Thus, if you change the beginning cell to $A$5, you should change the
final part of the formula to -4.

=OFFSET(Sheet1!$A$2,0,0,COUNTA(Sheet1! $A:$A)-1)
6. Click OK (Excel 2007) or Add (older versions). Excel creates the name and associates it
with the formula you entered. In versions of Excel prior to Excel 2007 the Define Name
dialog box should still be visible, with the newly defined name listed.
7. If you are using Excel 2007, again display the New Name dialog box by displaying the
Formulas tab of the ribbon and clicking Define Name.
8. In the Names in Workbook or Name field (depending on your version of Excel) enter a
name that will refer to the data in column B.
9. In the Refers To field, enter the following formula. (You should make the same type of
changes to the sheet name, beginning cell, and final part of the formula as described in step
5.)

=OFFSET(Sheet1!$B$2,0,0,COUNTA(Sheet1!$B:$B)-1)
10. Click OK (Excel 2007) or Add (older versions). Excel creates the name.
11. If you are using a version of Excel prior to Excel 2007, click OK to close the Define Name
dialog box.
12. Display the chart and select the data series. (There should only be one data series, since this
is a simple two-column data table.) The formula bar will display a formula similar to the
following:

=SERIES(Sheet1!$B$1,Sheet1!$A$2:$A$32, Sheet1!$B$2:$B$32,1)
13. Replace the ranges in the formula with the names you defined earlier in these steps.
Assuming you defined the names Dates and Readings in steps 6 and 9, the formula should
look like this:

=SERIES(,Sheet1!Dates,Sheet1!Readings,1)
Now the chart will update automatically regardless of where you add information in your data table.
This works because the names you defined in steps 6 and 10 refer to a formula that calculates the
extent of data in columns A and B of your worksheet.

There are many other ways that you can create dynamic ranges, depending on the characteristics of
the data you are using. For additional information, see these Web resources:

http://j-walk.com/ss/excel/usertips/tip053.htm
http://www.ozgrid.com/Excel/DynamicRanges.htm

Changing Elements in Lots of Charts at One Time


If you find yourself using a "non-default" chart often (which means changing the appearance of
certain chart elements after the chart is created), then a great approach is to create a custom chart
and save that format in Excel. You can then use the saved format to create all your new charts,
thereby minimizing the amount of later formatting you need to do. How you save custom chart
formats has been covered in other issues of ExcelTips.

Custom chart formats may be great for the future, but it doesn't help if you already have a whole
bunch of charts in an existing workbook. In that case, the best solution is to use a macro which can
step through all the charts in a workbook and make a desired change. You just need to decide up
front which items you wish to change, and then program the macro to specifically change those
items.

For example, the following macro changes the font color and size of the Y-axis labels. It loops
through all the charts in the workbook, both sheets and embedded charts.

Sub ChangeAllCharts1()
Dim cht As Chart
Dim sht
Dim ChtObj As ChartObject

For Each cht In ActiveWorkbook.Charts


With cht.Axes(xlValue).TickLabels.Font
.Size = 20
.Color = vbRed
End With
Next

For Each sht In ActiveWorkbook.Sheets


For Each ChtObj In sht.ChartObjects
With ChtObj.Chart.Axes(xlValue).TickLabels.Font
.Size = 20
.Color = vbRed
End With
Next
Next
End Sub

As written here, the macro changes the font size to 20 and the color to red. If you want the macro to
change other elements, all you need to do is change the With statements to reflect the elements you
want changed, or you could use a For...Next loop to step through all the chart elements. The
following macro exhibits this technique, changing the background color of the charts in a
workbook.

Sub ChangeAllCharts2()
On Error Resume Next
NewChartAreaColor = 34

For J = 1 To ActiveWorkbook.Charts.Count
ActiveWorkbook.Charts(J).Select

'The pairs of line code indicate desired changes


ActiveChart.ChartArea.Select
Selection.Interior.ColorIndex = NewChartAreaColor
Next J

For J = 1 To ActiveWorkbook.Sheets.Count
For K = 1 To Sheets(J).ChartObjects.Count
Sheets(J).Select
Sheets(J).ChartObjects(K).Activate

'The pairs of line code indicate desired changes


ActiveChart.ChartArea.Select
Selection.Interior.ColorIndex = NewChartAreaColor
Next K
Next J
End Sub

Reading Values from Graphs


When creating charts from Excel data, you can smooth out the lines between data points by using
any number of methods. At some point, you may want to actually figure out how Excel does its
calculations to determine where to actually plot points along the line. Rather than visually trying to
figure out where a point falls, you can follow these steps:
1. Right-click on the data series in question. Excel displays a Context menu.
2. Choose the Add Trendline option from the Context menu. Excel displays the Add Trendline
dialog box; in Excel 2007 it is the Format Trendline dialog box. Make sure the regression
type you want to use is selected.
3. Display the Options tab. (In Excel 2007 it is the Trendline Options tab.)
4. Make sure the Display Equation on Chart check box is selected.

The result is that Excel shows a formula, on the chart, that represents how it calculated each point
along the line. You can then use this formula to determine points, as well. No more guessing! Once
you know the formula, you can turn off the formula display if you want it off.

If you would like to know the different formulas that Excel uses for different types of trend lines,
you can use the online Help system to search for "equations for calculating trendlines."

Easily Changing Chart Data Ranges


If you change the data range for your chart quite often, it can get tiresome to continually pull up the
Chart Wizard and change the data range reference. For instance, if you have a data table that
includes several years worth of data, you may want to view a chart that is based on the first five
years of data, and then change the data range so the chart refers to a different subset of the data.
Make the changes often enough in the Chart Wizard, and you'll start casting about for ways to make
the changes easier (and more reliably) than with the wizard.

One way to do this is with the use of named ranges and several worksheet functions. Let's say that
your chart is embedded on a worksheet, but the worksheet is different than the one where the source
data is located. On the same sheet as the chart, create two input cells which will serve as "from" and
"to" indicators. Name these two cells something like FromYear and ToYear.

On your data worksheet (the one without the chart; I'll call it "Source Data"), the data is arranged
with each year in a separate column and a series of cost factors in each row. Start your table in
column F and place your years in row 2. Place the cost factors in column E, starting at row 3.
Above the years place a capital letter that is the same as the column letter, and in column D place a
number that is the same as the row number of the data. The attached figure shows how the data
should look. In this example, the chart that is embedded on the other worksheet is based on the data
in the rangeF2:I5. There is nothing special about the chart, but the changes you are getting ready to
make will make it dynamic, and therefore much more useful.

Start by placing the following formula in cell B1:

="Trends For " & IF(FromYear=ToYear,FromYear,FromYear & " to " & ToYear)

This formula provides a dynamic title that you will later use for your chart. Give cell B1 the name
addrTitle, then place the following formula in cell B2:

="'Source Data'!$" & INDEX($F$1:$I$1,1,MATCH(FromYear,$F$2:$I$2)) & "$" & D2 &


":$" & INDEX($F$1:$I$1,1,MATCH(ToYear,$F$2:$I$2)) & "$" & D2

Copy the formula in B2 to the cells B3:B5. The formula returns address strings that represent the
desired ranges for the X-axis values and the data series. The actual ranges returned by the formulas
will vary, based on the values you enter in the FromYear and ToYear cells on the other worksheet.
To make things clearer you can enter some labels into column A, as shown in the accompanying
figure. Now you need to name each of the cells in the range B2:B5. Select B2 and in the Name Box
(just above column A) enter the name "addrXVal" (without the quotes). Similarly name B3 as
addrCost1, B4 as addrCost2, and B5 as addrCost3.

The next step is to create a couple of named formulas that you can use in creating the charts.
Choose Insert | Name | Define to display the Define Name dialog box. In the name area, at the top
of the dialog box, type "rngXVal" (without the quotes), then type the following in the Refers To
box:

=INDIRECT(addrXVal)

Using the same dialog box, define additional names (rngCost1, rngCost2, and rngCost3) that use the
same type of INDIRECT formula to refer to the ranges addrCost1, addrCost2, and addrCost3,
respectively.

Now you are finally ready to update the references in your chart. Right-click the chart and select
Source Data, then make sure the Series tab is displayed. For each of the data series listed at the left
side of the dialog box, enter the Name and Values according to the names you defined. Thus, for the
Cost1 series you would enter a Name of ='Source Data'!addrCost1 and a Values of ='Source Data'!
rngCost1. You would use the similar references and names for each of the other data series, as well.

Note that you must include the name of your worksheet (Source Data), within apostrophes, in the
references you enter. In the Category (X) Axis Labels reference you can enter ='Source Data'!
rngXVal.

Once this is done, you can change the starting and ending years in the FromYear and ToYear cells,
and Excel automatically and immediately updates the chart to represent the data you specified.
For an extra touch, if you haven't already added a chart title, go ahead and do so. Right-click the
chart and select Chart Options, then display the Titles tab. Enter anything you'd like in the Chart
Title box (you'll replace it in a moment), then click OK. The chart title should already be selected,
but if it isn't, click on it once. You should see the selection box around the title. In the Formula bar
enter the following:

='Source Data'!addrTitle

The chart title is now linked back to the cell containing the title string, which in turn is dynamically
updated each time you change the FromYear and ToYear values.

Adding AutoShapes
The graphics features of Excel allow you to add a number of predefined shapes to a workbook.
These shapes, called AutoShapes, cover a wide range of needs. If you want to add shapes to the
AutoShapes feature, however, you are out of luck. The shapes are apparently hard-coded into Excel,
and cannot be modified.

You can, however, add shapes to the Clip Gallery. If you format the shapes as WMF files, they are
easy to add and easy to place within a worksheet. For instance, if you have a number of different
flowchart symbols that you want to make available in Excel, all you need to do is save each symbol
in the WMF format, and then import them into the Clip Gallery. (To save graphics in the WMF
format, you will need to use a specialized graphics program, such as Paint Shop Pro or Corel Draw.)

If you don't want to use the Clip Gallery for some reason, you can simulate your own AutoShapes
through a combination of macros and graphics in a hidden worksheet. The following general steps
detail how to do this for a series of twenty flowchart symbols. The steps assume that you are
reasonably comfortable writing macros and customizing toolbars.

1. Open a template workbook, and make sure it has only a single worksheet.
2. Place all the flowchart graphics on the worksheet.
3. Create a new toolbar, name it MyShapes, and make sure it is associated with the template
workbook.
4. Add twenty buttons to the toolbar, one for each flowchart graphic. The idea is that clicking a
button will add the associated flowchart shape to the active worksheet.
5. Edit each button face to show as closely as possible each flowchart graphic. (This is the
toughest part of these steps).
6. Change the ToolTip text for each button, as desired. This is helpful so the user can
understand the purpose of each flowchart graphic.
7. In turn, select and name each of the flowchart graphics. (You name the graphics by selecting
them and entering a name in the Name box at the left of the Formula bar.) For the purposes
of these steps, assume you use names such as FlowObj1, FlowObj2, etc.
8. Write twenty macros (one for each flowchart graphic) of the following kind:

Sub AddFlowObj1()
ThisWorkbook.Sheets(1).Shapes("FlowObj1").Copy
ActiveSheet.Paste
End Sub
9. Assign each of the macros to the corresponding toolbar button.
10. In the Workbook module of the template, add the following procedures:

Private Sub Workbook_Open()


Application.CommandBars("MyShapes").Visible = True
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.CommandBars("MyShapes").Delete
End Sub
11. Save the template as an Excel add-in.
12. Restart Excel and use Tools | Add-ins to active your new add-in.

Specifying the Size of Chart Objects


When you create a Excel chart, as an object to be placed in a worksheet, the chart object is
automatically sized to some pre-determined size that Excel selects. You may not want the chart
object to be whatever size Excel determines; you may want your chart objects to always be a
standard size, so they always appear the same relative to your worksheets.

There is no way to specify a chart object size as you are creating the chart. You can, however, resize
the chart object after it is created, just as you can resize other graphic elements of your worksheet.
You could write a macro to create the object at a particular size, but doing so would remove much
of the flexibility that is inherent in Excel's chart-creation tools. For instance, when you specify the
size of the chart object being created, you also have to specify other characteristics, such as chart
type. It is easier to pick and choose such characteristics through the tools on the ribbon than it is to
do so in a macro.

You can, however, easily create a macro that will resize an existing chart object. The key
commands of such a macro would be changing the Width and Height properties for the chart object.
In VBA, these properties are specified in points. Thus, if you wanted to resize the chart object so it
was 4 inches high, you would set the Height property to 288, which is the number of points in 4
inches (4 * 72).

The following macro gives an example of one way to step through all the chart objects on a
worksheet and make them the same size. This particular macro sets the width of each chart object to
4 inches, and the height to 3 inches.

Sub ResizeCharts()
For j = 1 To ActiveSheet.Shapes.Count
If ActiveSheet.Shapes(j).Type = msoChart Then
ActiveSheet.Shapes(j).Width = 4 * 72
ActiveSheet.Shapes(j).Height = 3 * 72
End If
Next j
End Sub

Two-Level Axis Labels


With some types of data, you may have a need for two-level axis labels for your chart. For instance,
you may want something similar to the following along the X-axis for your chart:

Pro | Team | Reg | Pro | Team | Reg ...


Eastern US | Western US ...

Setting up such an arrangement in an Excel worksheet is easy, but getting the same result in a chart
may not be as obvious.
Go ahead and set up your worksheet to reflect the column titles the way you want them. These
column titles will end up as your X-axis labels. You could set them up as follows:

| A | B | C | D | E | F | G |
1 | | Eastern US | Western US |
2 | | Pro | Team | Reg | Pro | Team | Reg |
1. In the first row, put your first major group title into cell B1.
2. Put your second major group title into cell E1.
3. In cells B2:G2 place your column labels.
4. Select cells B1:D1 and click the Merge and Center tool. (In Excel 2007 the Merge and
Center tool is in the Alignment group of the Home tab on the ribbon.) The first major group
title should now be centered over the first group of column labels.
5. Select cells E1:G1 and click the Merge and Center tool. The second major group title should
now be centered over the second group of column labels.
6. Make the cells at B1:G2 bold. (This sets them off from your data.)
7. Place your row labels into column A, beginning at cell A3.
8. Place your data into the table, beginning at cell B3.

With your table completed, you are ready to create the chart. Just select your data table, including
all the headings in the first two rows, then create your table. Excel automatically recognizes that
you have two rows being used for the X-axis labels, and formats the chart correctly. Since the
X-axis labels appear beneath the chart data, the order of the label rows is reversed—exactly as
mentioned at the first of this tip.

Removing Pictures for a Worksheet in VBA


If you are having a problem deleting pictures using a macro, it could be due to either bad syntax or
different groupings of the images.
There are a couple of things to check out. First of all, you should ensure that you are using the
proper syntax to do the deletion. Check to make sure you are explicitly including the sheet object in
your code. For instance, the following line will not work:

Shapes(1).Delete

Instead, you must specify the sheet, using code similar to any of the following lines:
ActiveSheet.Shapes(1).Delete
Sheets("Sheet1").Shapes(1).Delete
Sheets(1).Shapes("Signature").Delete

If you determine that the expected image is not in the Shapes collection, then
it is possible that Excel (for strange reasons only known to Excel) moved the
image to a different collection, such as the Pictures collection. If you suspect
this, then try using the following macro:

Sub WhatAmI()
Dim sTemp As String

sTemp = "You selected this type of object: " & TypeName(Selection)


sTemp = sTemp & vbCrLf
sTemp = sTemp & "It's name is " & Selection.Name
MsgBox sTemp
End Sub

Select the signature image, then run the macro. You should see a message box
that indicates the type of object you selected, along with its name. You can
then use the information to modify your macro so it deletes the image, as
desired.

Negatives in Pie Charts


Excel allows you to easily create charts based on the data in a worksheet. If you create a pie chart,
Excel charts negative values as if they were positive (in other words, it uses the absolute value).
You may, however, prefer to have the negative values charted as if they were zero—to not have a
slice of the pie.
Normally, people create pie charts based on a simple set of values. Each value within the series
represents a portion of the whole. Thus, pie charts are often created based on the result of some sort
of formula, such as the sum of values in a column; the sums of each column are the basis for the pie
chart. Instead of using a standard SUM formula for the values to be charted, you could use a
formula such as the following:

=IF(SUM(D7:D11)<0,0,SUM(D7:D11))

In this case, the value to be charted is set to zero if the sum is less than zero, or it reflects the actual
total if the sum is zero or above.
If your data is conducive to filtering, you could also set up a filter so that negative values are
filtered out. This will cause those values to be ignored in the chart created by Excel.
Of course, all this being said, one would have to wonder if a pie chart is the appropriate chart for
representing Frances' data in the first place. After all, pie charts represent portions of a whole—yet
by filtering or adjusting totals, portions of the whole are being removed. Granted, they are negative
portions, but they are portions nonetheless.
Pie charts, by their nature, are not well-suited for displaying negative numbers. If negative numbers
are expected, then column or bar charts are a much more appropriate choice. Why? Because they
can represent data that falls to the left of or below a baseline—as is appropriate for negative
numbers.
INSERIMENTO E CONVALIDA DATI
Verifica di input di un dato
Sub IF_con_variabili()
Dim myDate As String
myDate = Inputbox("Inserisci data")
If myDate <> "" Then
    If IsDate(myDate) Then
    Range("b3").FormulaR1C1 = myDate
    Else
    Range("b3").FormulaR1C1 = "re-immetti data"
    End If
End If
End Sub

Creating Dependent Drop-Lists


Create drop-down lists so that the second drop-down list is dependent on the selection made in the
first drop-down list.

There are actually a number of different ways you can accomplish this task, ranging from simple
formulas to complex macros. The method you choose depends, most directly, on the type of drop-
down lists you want to create. There are actually three types of drop-down lists you can create in
Excel:

 Validation lists. If you want to limit input in certain cells, then you can create drop-down
validation lists.
 Forms lists. You can use the Forms toolbar (View | Toolbars | Forms) to create drop-down
lists. These are great if you are going to create a protected Excel form.
 Userforms. These are dialog boxes, created in the VBA editor. You "run" a userform by
calling it from a macro. This is the most versatile form of user interface, as it allows you the
greatest latitude in what the user sees. (It also requires the most advanced knowledge of
Excel in order to create.)

Rather than discuss how to create dependent drop-lists based on each of these types of drop-down
lists, I'll choose to examine the simplest method, which will suffice for most people. If you use the
INDIRECT function along with data validation lists, it is quite easy to get the result you want:

1. On a blank worksheet in your workbook, create a list of the items that will be in the first
drop-down list. For instance, create a list of departments in your company, such as Sales,
Research, Executive, Production, etc. (These should be single-word entries in the list.)
2. Select the list of items you created in step 1 and name the range using a name such as
"Departments."
3. On the same worksheet, create a list of items that could appear in the secondary drop-down
list. There should be one list for each entry in the list you made in step 1. For instance, you
could create a list of Sales personnel, a list of Research personnel, etc.
4. List by list, select the lists you created in step 3. Give each list a single-word name that
matches the names used in the list in step 1, i.e., Sales, Research, Executive, etc.
5. Switch to the worksheet where you want to have the drop-down lists appear.
6. Select the cells where users should be able to enter items from your first list--the one created
in step 1.
7. Choose Validation from the Data menu or, if you are using Excel 2007, click the Data tab of
the ribbon, then click the Data Validation option in the Data Tools group. Excel displays the
Data Validation dialog box.
8. Using the Allow drop-down list, choose List.
9. In the Source box, enter an equal sign followed by the name you created in step 2. For
instance, =Departments.
10. Click OK. You have now specified that only information from your first list can be entered
into the cells you selected in step 6.
11. Select the cells where users should be able to enter items from the dependent lists. For
instance, select the cells just to the right of the cells you selected in step 6.
12. Choose Validation from the Data menu or, if you are using Excel 2007, click the Data tab of
the ribbon, then click the Data Validation option in the Data Tools group. Excel displays the
Data Validation dialog box.
13. Using the Allow drop-down list, choose List.
14. In the Source box, enter a formula that uses the INDIRECT function. If the first cell of the
range selected in step 11 is cell B3, and you want that first cell to be dependent on what is
chosen in cell A3, then you would use the following formula:

=INDIRECT(A3)

That's it. Now people can only select from your major list if they are using one of the cells specified
in step 6, and from the appropriate dependent lists if they choose one of the cells in step 11.

There are lots of different variations of this approach (using data validation). You can find more
information on some of these approaches by visiting these Web pages:

http://www.ozgrid.com/download/ (download the MatchingLists.zip file)


http://www.contextures.com/xlDataVal02.html

Unique Name Entry


If you need to make sure that a column contains only unique text values, you can use data validation
for the task. This won't help when someone decides to copy and paste information, however. For
instance, if you type "George" into cell A8, and then type "George" into A9, regular data validation
will generate an error, as one would expect, indicating that the value you are trying to enter is not
unique. However, if you type "George" into cell A8, copy that cell and paste it into cell A9, no data
validation error is triggered--the paste is allowed.

There is no direct way around this in Excel. You can, however, cause Excel to do some checking
whenever you try to do a paste. Consider the following macro:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)


On Error Resume Next
For Each TmpRng In Target
TmpVal = TmpRng.Validation.Type
If TmpVal > 0 Then
If Application.CutCopyMode = 1 Then
MsgBox "You cannot paste into validated cells."
Application.CutCopyMode = False
Exit Sub
End If
End If
Next
End Sub
This macro is only run when the selection changes in a worksheet. (This code needs to be in the
code window for a worksheet.) It examines the target cells (the ones being selected), and if the user
is trying to paste into a cell that has validation active, it will not allow it. Further, the user will see a
dialog box that indicates the error.

You should note that this routine just checks to see if pasting into a data-validated cell is being
done. If it is, then an error is generated. The routine does not check to see if what is being pasted is
actually permissible under the validation rules in the target cells; that would be much more complex
and require quite a bit more coding.

Limiting Input to a Format


As you are developing a spreadsheet, you may want to limit what users are able to put into a
particular cell. For instance, you might want to make sure that entries in a cell are exactly four
characters long, begin with the number 6, are followed by any digit, then by a letter, and then by
any digit.

There are three ways to go about such a validation. The first, of course, is to write a macro that will
check input and ensure that the entries follow the desired pattern. Another method, without using
macros, is to rely upon the data validation feature of Excel. If the number of valid entries is not
terribly long, you might try these general steps:

1. On a blank worksheet, construct a list of the valid entries.


2. On the worksheet used for input, highlight the cell into which the entry will be made.
3. Choose Validation from the Data menu. Excel displays the Data Validation dialog box. To
display the dialog box in Excel 2007 display the Data tab of the ribbon and click Data
Validation in the Data Tools group.
4. Using the Allow drop-down list, choose List.
5. With the insertion point in the Source box, choose the list you put together in step 1 and
click on OK.

Now, whenever someone tries to enter data that is not included in your list of acceptable values, the
validation rules kick into effect and the user is forced to change the entry.

You can also use the data validation feature in a bit of a different way. If you have well-defined
rules for your data entry then you can put together a formula that describes a valid entry. The
following is one such formula:

=AND((LEN(A1)=4),(LEFT(A1,1)="6"),(ISNUMBER(VALUE( _
(MID(A1,2,1))))),(CODE(MID(UPPER(A1),3,1))>64),(CODE( _
MID(UPPER(A1),3,1))<91),(ISNUMBER(VALUE((MID(A1,4,1))))))

Remember that this is a single formula, entered all on one line, using the following general steps:

1. Highlight the cell into which the entry will be made. (The above formula assumes you are
using cell A1. If a different cell is selected, you will need to make the appropriate reference
changes to the above formula.)
2. Choose Validation from the Data menu. Excel displays the Data Validation dialog box. (To
display the dialog box in Excel 2007 display the Data tab of the ribbon and click Data
Validation in the Data Tools group.)
3. Using the Allow drop-down list, choose Custom.
4. Enter the above formula in the Formula box. (All one line, no spaces.) and click on OK.
You may get an error when you click on OK, based on the contents of A1. (Excel may try to tell
you that the contents of A1 don't validate according to the rule.) This is OK; the validation rule you
are setting up will come into play when someone tries to enter something in the cell.

The formula basically pulls apart the entry being made and determines if each character is within
bounds. If not, then the result of the formula is FALSE, and the validation rules come into play.

Limiting Entry of Names


Using Excel for entering data is quite common. When you are entering information, you may want
to limit what can be placed in a particular cell. For instance, you might be working on an employee
register, and you need to make sure that you only enter each employee's name a single time in the
worksheet. One way to approach this challenge is to create a list of allowable names, either on
another worksheet or in a different place on the same worksheet. Give this list of names a defined
name, such as ValidNames. Then, follow these steps:
1. Choose the cells where you will be entering employee names; the ones where you want to
make sure you only enter each name once. (For this example, let's assume you select cells
A1:A10.)
2. Display the Data Validation dialog box. (If you are using Excel 2007, display the Data tab of
the ribbon and click the Data Validation tool. If you are using an older version of Excel,
click Data | Validation. )
3. Make sure the Settings tab is displayed.
4. In Allow drop-down list, choose Custom.
5. In the Formula box (which appears when you complete step 4), enter the following formula:

=AND(COUNTIF(ValidNames,A1)=1,COUNTIF($A$1:$A$10,A1)=1)

This validation formula works because it checks the input range (A1:A10) and makes sure that no
more than one name from the ValidNames list appears there. There are many other variations on
this particular formula that can be used, since Excel does provide many different ways to
accomplish the same task. An example of an alternate formula method is provided in the Microsoft
Knowledge Base:

http://support.microsoft.com/?kbid=213185

While the Knowledge Base article is specifically for Excel 2000, the formula that is at the root of
the article (step 7) will work just fine in other versions of Excel.

These formulaic methods work great if you are typing names into your input list. If you instead
prefer to use a drop-down list to select names, there is a slick method presented at this Web page:

http://www.contextures.com/xlDataVal03.html

What makes it slick is that the drop-down list is dynamic. For instance, when you select a name to
go into one cell, that name is removed from the drop-down list used to select names in other cells.
Conditional Format that Checks for Data Type
A conditional format can be used to draw attention to when an improper value (text or numeric) has
been entered in a cell, but a more robust approach might be to prohibit the improper value from
being entered in the first place. This can be done with the data validation capabilities of Excel.
More information can be found here:

http://excel.tips.net/E165_Data_Validation.html

Using data validation you can specify the type and range of data permitted in a cell, along with how
stringently you want that specification followed. If you prefer to not use data validation for some
reason, you can set up a conditional format that will verify if the information placed in a cell is of
the data type you want. Follow these steps if you are using Excel 2007:

1. Select the cells that you want conditionally formatted.


2. With the Home tab of the ribbon displayed, click the Conditional Formatting option in the
Styles group. Excel displays a palette of options related to conditional formatting.
3. Choose Highlight Cells Rules and then choose More Rules from the resulting submenu.
Excel displays the New Formatting Rule dialog box.
4. In the Select a Rule Type area at the top of the dialog box, choose Use a Formula to
Determine Which Cells to Format.
5. In the Format Values Where This Formula Is True box, enter one of the following formulas.
(The first is if you want to highlight the cell if it contains text; the second if it contains a
number. Make sure you replace A1 with the cell address of the cell in the upper-left corner
of the range selected in step 1.)

=ISTEXT(A1)
=ISNUMBER(A1)
6. Click Format to display the Format Cells dialog box.
7. Using the controls in the dialog box, specify a format that you want used for those cells
selected in step 1. For instance, you may want bold text in a red typeface.

If you are using an older version of Excel, follow these steps instead:

1. Select the cells that you want conditionally formatted.


2. Choose Conditional Formatting from the Format menu. Excel displays the Conditional
Formatting dialog box.
3. In the drop-down Condition list, choose Formula Is.
4. In the formula box, enter the one of the following formulas. (The first is if you want to
highlight the cell if it contains text; the second if it contains a number. Make sure you
replace A1 with the cell address of the cell in the upper-left corner of the range selected in
step 1.)

=ISTEXT(A1)
=ISNUMBER(A1)
5. Click on Format. Excel displays the Format Cells dialog box.
6. Using the controls in the dialog box, specify a format that you want used for those cells
selected in step 1. For instance, you may want bold text in a red typeface.

CONVALIDA di Dati di Latitudine in input


The user has two cells in which enter degrees and minutes, which represent latitude. The values can
necessarily vary from 0 degrees and 0 minutes to 90 degrees and 0 minutes. For the degrees the
value is between 0 and 90. The value in the minutes cell can vary from 0 to 59, unless the degrees
cell is 90, then the only acceptable value is 0 minutes.

Assuming that degrees go into cell A1, validation for the degrees could be set up as:

1. Select cell A1.


2. Display the Data tab of the ribbon.
3. In the Data Tools group click the Data Validation tool. Excel displays the Data Validation
dialog box.
4. The Settings tab should be displayed.
5. Using the Allow drop-down list, choose Whole Number.
6. In the Minimum and Maximum boxes enter 0 and 90, respectively.
7. Adjust the settings on the other tabs of the dialog box, as desired.

Now, assuming that minutes into cell B1, validation could be set up for the minutes in this manner:

1. Select cell B1.


2. Display the Data tab of the ribbon.
3. In the Data Tools group click the Data Validation tool. Excel displays the Data Validation
dialog box.
4. The Settings tab should be displayed.
5. Using the Allow drop-down list, choose Whole Number.
6. In the Minimum box enter 0.
7. In the Maximum box enter =IF(A1=90,0,59)
8. Adjust the settings on the other tabs of the dialog box, as desired.

The formula used for the Maximum value (step 7) sets a maximum for the cell based on whatever is
entered into cell A1 (the degrees).

Limiting Choices in a Cell


When you are developing worksheets that will be used by others, you may want to limit what your
users can enter into a particular cell. For instance, you might have a cell where the user should enter
their department. You would obviously want them to only enter one of the valid departments for
your company.

To ensure that only certain departments can be entered in the cell, follow these steps:

1. Select the cell where the user will input the department name.
2. In the Data Tools group click the Data Validation tool. Excel displays the Data Validation
dialog box (Excel 2003 and earlier: Choose Validation from the Data menu. Excel displays
the Data Validation dialog box).
3. The Settings tab should be displayed. Using the Allow drop-down list, choose List.
4. In the Source box, enter your department names, separated by commas.
5. Display the Error Alert tab. On this tab you specify an error message that the user will see if
they enter an improper department name.
6. In the Title field, enter the phrase "Enter Valid Department Name".
7. In the Error message box, enter a message that indicates what the user did incorrectly. You
should also indicate the acceptable department names.
That's it. Now, the user can only enter one of your valid department names. Better yet, when they
select the cell they will see a drop-down arrow at the right of the cell where they can select from the
department names you specified in step 5. If they enter one that is incorrect, they will see the error
message and will need to change what they entered.
RANGES
Avoid the use of Copy and Paste whenever possible
Sub NoCopyAndPaste()

'Instead of:

Sheet1.Range("A1:A200").Copy
Sheet2.Range("B1").pasteSpecial
Application.CutCopyMode=False 'Clear Clipboard

'Use:

Sheet1.Range("A1:A200").Copy Destination:=Sheet2.Range("B1")

'Or, if only values are needed:

Sheet2.Range("B1:B200").Value= Sheet1.Range("A1:A200").Value

'Or, if only formulae are needed:

Sheet2.Range("B1:B200").Formula = Sheet1.Range("A1:A200").Formula

'See also FormulaArray and FormulaR1C1 etc


'Instead of:

Sheet1.Range("A1:A200").Copy
Sheet1.Range("A1:A200").PasteSpecial xlPasteValues
Application.CutCopyMode=False 'Clear Clipboard

'Use:

Sheet1.Range("A1:A200") = Sheet1.Range("A1:A200").Value

End Sub

Inserting a Relative formula into a range of cells: Faster than AutoFill or Copy.
Range("A1:A200").FormulaR1C1 = "=SUM(RC[1]:RC[5])"

Autoriempimento di un Range con un pattern


Dato un range che inizia in A1, lo riempie a partire da D1 fino alla fine con il contenuto di D1:E1

Sub var_ultimacella()
Dim myr As Range
Dim LC As Range

Set myr = Range("A1").CurrentRegion


Set LC = myr.Cells(myr.Cells.Count)

Range("D1:E1").AutoFill Destination:=myr.Range("D1", LC)


End Sub

??????????????????????????
Sub sommadicolonna_e_address()
Dim Ranget As Range, MyTot As Range
Set Ranget = Range("B4:H19")
Set MyTot = Ranget.Offset(Ranget.Rows.Count).Rows(1)
MyTot.Cells(1) = Ranget.Columns(1).Address
'MyTot.Cells(1) = Ranget.Columns(1).Address(False, False)
MyTot.Formula = "=SUM(" & Ranget.Columns(1).Address(False, False) & ")"
With MyTot.Font
    .FontStyle = "Grassetto Corsivo"
End With
End Sub

FUNZIONE: Trovare l’ultima riga o cella non vuota


Function xlLastRow(Optional WorksheetName As String) As Long
    If WorksheetName = vbNullString Then WorksheetName = ActiveSheet.Name
    With Worksheets(WorksheetName)
        On Error Resume Next
        xlLastRow = .Cells.Find("*", .Cells(1), xlFormulas, _
        xlWhole, xlByRows, xlPrevious).Row
        If Err <> 0 Then xlLastRow = 0
    End With  
End Function

Selezionare l’ultima cella non vuota del foglio


Sub ultimacella_selezionecorrente()
    Dim MyRange As Range
    Set MyRange = Range("i8").SpecialCells(xlLastCell)
    Range("a2").Select
    ActiveCell.CurrentRegion.Select
    Selection.End(xlDown).Select
End Sub

Seleziona l'ultima cella non vuota del foglio partendo dalla cella attiva
Sub ultimacella_selezionecorrente ()
    ActiveCell.SpecialCells(xlLastCell).Select    'seleziona la
prima cella dell'ultima riga in cui è scritto qualcosa
'
solo per l'area corrente della cella selezionata
    Range("a2").Select
    ActiveCell.CurrentRegion.End(xlDown).Select
End Sub

Selecting the First Cell In a Row


Once executed, the selected cell becomes the first cell (in column A) of the current row. If you run
this line while a range of cells is selected, then the cell in column A of the first row of the selection
is selected:

Cells(ActiveWindow.RangeSelection.Row, 1).Select

Selezionare un range a partire da una cella singola


Sub select_range ()
Range(Activecell, Activecell.Offset(0,4)).Select
‘seleziona la cella attiva ed altre 4 a dx
End Sub
Incolla formula su un range e ne aggiunge la somma tipo R1C1
Range("B12:K12"). Copy
Sheets("nomefoglio").Select
Range("B45").Select
Selection.PasteSpecial Paste:=xlPasteFormulas
numrow = -(ActiveCell.Row - 1)
For i = 1 To 7
ActiveCell.Offset(0, i).FormulaR1C1 = "=SUM(R[" + Str(numrow) + "]C:R[-1]C)"
Next

Scopre e nasconde n colonne prima della cella attiva


Sub ScopriNascondi()
For i = 1 To n
ActiveCell.Offset(0, -i).EntireColumn.Hidden = Not
_(ActiveCell.Offset(0, -i).EntireColumn.Hidden)
Next
ActiveCell.Select
End Sub

Definizione di un intervallo come caratteristiche e area


Sub Intervalli()
Dim MyRange As Range
Set MyRange = Range("C3:F8")
MyRange.Select
End Sub

Spostarsi sulla cella/riga successiva al range definito


Sub spostarsi_sotto_un_intervallo()
Dim MyRange As Range, MyNewRange As Range
Set MyRange = Range("B4:H19")
MyRange.Cells(MyRange.Cells.Count).Select
'selezione dell'ultima cella dell'intervallo
Set MyNewRange = MyRange.Offset(1, 0) 'creazione di un nuovo intervallo

'uguale spostato in sotto di una riga


MyNewRange.Select
MyNewRange.Rows(MyNewRange.Rows.Count).Select
‘seleziona l'ultima riga del nuovo intervallo che

‘coincide con la prima riga successiva al vecchio


Selection.Range("A1").Select 'ora si può selezionare la prima cella
‘di tale riga che sta sotto al vecchio
'le ultime due operazioni sono riassumibili in una:
MyNewRange.Rows(MyNewRange.Rows.Count).Range("A1").Select
'in alternativa si può ottenere lo stesso risultato
‘senza creare un nuovo intervallo:
MyRange.Rows(MyRange.Rows.Count).Select
Selection.Offset(1, 0).Range("a1").Select
' anch'essa scrivibile in una sola riga:
MyRange.Rows(MyRange.Rows.Count).Offset(1, 0).Range("a1").Select
End Sub

Cancellazione del contenuto di un range


Sub CancellaContenuto()
Range("a1:b3").ClearContents
End Sub

Valorizzare un intervallo
Sub Scrivere_nelle_celle()
Selection.FormulaR1C1 = "----"
End Sub

Copiare un intervallo
Sub Copia_Incolla()
Selection.Copy
Range("c20:G20").PasteSpecial
Application.CutCopyMode = False
End Sub

Copia dei valori di un range da un foglio ad un altro


Sub selezione_intervallo_pieno()
Dim Interv As Range
Sheets("Foglio2").Activate
Range("d4").Activate
Set Interv = Range(ActiveCell.End(xlToRight), ActiveCell.End(xlDown))
Interv.Copy
Sheets("Foglio1").Activate
    Range("G10").PasteSpecial Paste:=xlPasteValues
    Application.CutCopyMode = False
End Sub

Cancellazione di righe consecutive


Sub Cancella_righe()
    Rows("20:33").Delete Shift:=xlUp
End Sub

FUNZIONE: saltare le celle vuote nella definizione di un intervallo


Function CoolRange(MyRange As Range, Optional NoNumbers As Boolean, Optional
_NoTexts As Boolean) As Range
    Dim RgConstants As Range, RgFormulas As Range
    Dim MyOption As Integer
'string to consider optional values
       
    If NoNumbers = False Then MyOption = 1
    If NoTexts = False Then MyOption = MyOption + 2
       
        MyOption = MyOption + 20
    On Error Resume Next
    Set RgConstants = MyRange.SpecialCells(xlCellTypeConstants, MyOption)
    Set RgFormulas = MyRange.SpecialCells(xlCellTypeFormulas, MyOption)
   
    On Error GoTo 0
    Select Case True
        Case RgConstants Is Nothing And RgFormulas Is Nothing: Exit Function
        Case RgConstants Is Nothing: Set CoolRange = RgFormulas
        Case RgFormulas Is Nothing: Set CoolRange = RgConstants
        Case Else: Set CoolRange = Union(RgConstants, RgFormulas)
    End Select
    Set RgConstants = Nothing
    Set RgFormulas = Nothing
End Function

Using Named Ranges in a Macro


To access the named range using the Range object, all you need to do is provide the name of the
range as a parameter to the object. This name is the same one that you defined within Excel. For
instance, the following line could be used to change the interior color of the entire range:

Worksheets("Sheet1").Range("Account").Interior.Color = vbYellow

Note that the Range object is used relative to a particular worksheet, in this case Sheet1. You could
also define a range object within VBA and then assign it to be equal to the named range, in this
manner:

Set rng = Worksheets("Sheet1").Range("Account")

The other method of using the named range is to use the Names collection. The following line will
again set the interior color of the range to yellow:

Workbooks("Book1.xls").Names("Account").RefersToRange.Interior.Color = vbYellow

Note that the Names collection is relative to the entire workbook, so it is not necessary to know
which worksheet the named range is associated with when you use this method of access. You can
also define a range object in VBA and assign it to be the same as the named range:

Set rng = Workbooks("Book1.xls").Names("Account").RefersToRange

You should know that the Names collection method of accessing a named range will only be viable
if you don't have the same named range defined on different worksheets in the workbook. If you do,
then you will need to use the Range object method, which requires the use of a specific worksheet
name in the reference.

Relative VBA Selections


If you want to select a single cell, relative to your current location, you can use the Offset method.
As an example, if you want to select the cell that is two rows down and one column to the right of
your current location, you could use the following:

ActiveCell.Offset(2, 1).Select

If you want to select a larger range than just a single cell, you can combine the Offset method with
the Address Method to find actual cell addresses, and then use your findings to actually select the
range itself. For instance, you might want to select the range that begins two rows down and one
column to the right, but then extends for four rows and three columns. You can accomplish this in
the following manner:

StartCell = ActiveCell.Offset(2, 1).Address


EndCell = ActiveCell.Offset(5, 3).Address
Range(StartCell, EndCell).Select

An alternative method of accomplishing the same task is to use the Resize method. In this
technique, you would first select the upper-right cell of the desired range (as was done in the first
use of Offset, above), and then use Resize to change the size of the selection. This is how it is done:
ActiveCell.Offset(2, 1).Select
Selection.Resize(4, 3).Select

Determining Rows and Columns in a Range


One of the handy worksheet functions provided by Excel allows you to determine the number of
rows and columns in a range. This is accomplished through the use of the ROWS and COLUMNS
functions. For instance, consider the following formula:

=COLUMNS(B2:D15)

The value returned is 3, since the range includes columns B, C, and D. You are not limited to
address ranges (such as B2:D15), but can also used named ranges with these functions.

Assegnare un valore a una cella distante saltando colonne nascoste


Sub Skip_hidden_columns ()
Dim col As Integer
col=0
Do While Columns(Activecell.Column + col).Hidden=True
col=col+1
Loop
Activecell.Offset(0,col)=”valoredaincollare”
End Sub

Getting Rid of Empty Rows after Importing


Sub DeleteEmptyRows()
Dim LastRow As Long
Dim J As Long

LastRow = ActiveSheet.UsedRange.Rows.Count + _
ActiveSheet.UsedRange.Rows(1).Row - 1
Application.ScreenUpdating = False
For J = LastRow To 1 Step -1
If Application.WorksheetFunction.CountA(Rows(J)) = 0 Then
Rows(J).Delete
End If
Next J
Application.ScreenUpdating = True
End Sub

Why would you want to use a macro? Because you may need to delete empty rows week after
week. Just put the macro into your Personal workbook and you can then access it whenever you
need.

Additional information on this topic can be found on these pages:

http://www.cpearson.com/Excel/deleting.htm#DeleteBlankRows
http://www.mvps.org/dmcritchie/excel/lastcell.htm

DeleteRowOnCell
This macro checks the selected column for blank cells. If any is found, the entire row is then
deleted.
Public Sub DeleteRowOnCell()

On Error Resume Next


Selection.SpecialCells(xlCellTypeBlanks).EntireRow.Delete
ActiveSheet.UsedRange

End Sub

Applying Range Names to Formulas


Named ranges can be a great boon when you are writing formulas. For instance, if you assign the
name TaxRate to cell A7, you can then use the name TaxRate in your formulas instead of A7. This
makes your formulas (and their purpose) easier to understand when you are later working with
them.

This approach is great if you have not yet created any formulas. What if you already have a bunch
of formulas in your worksheet, and they already reference cell A7 instead of TaxRate? You could,
of course, select each formula and edit them to refer to TaxRate instead of A7, but that could be a
long process that is prone to mistakes. (My fat fingers often introduce mistakes that I never
intended. )

The solution is to allow Excel to do the editing for you. It is easy to do; just follow these steps:

1. Define the named range you want used in your worksheet.


2. Select the cells that contain formulas.
3. Display the Formulas tab of the ribbon.
4. Click the down-arrow at the right of the Define Name tool (in the Defined Names group)
and then choose Apply Names. Excel displays the Apply Names dialog box. Click OK.

That's it; Excel examines your formulas and any reference to cell A7 is replaced with the name of
A7, TaxRate.

Copia delle sole celle visibili all’interno di un range


Utile, p.es., per copiare solo il risultato di un filtraggio:

Set copia = Range("A4", ActiveCell.Offset(0,15)).SpecialCells(xlCellTypeVisible)

Positioning a Column on the Screen


If you have static columns and dynamic columns on the screen, you may want the dynamic columns
to always show a particular range. E.G., assume that columns A:G are frozen. If we move to column
Z to start input, columns T:Z are placed to the right of the frozen columns A:G. This makes
columns Z:AF to appear to the right of A:G
Sub GotoCol1()
With Application
ActiveWindow.FreezePanes = False
Range("H1").Select
ActiveWindow.FreezePanes = True
.Goto Range("IV1")
.Goto Range("Z1")
End With
End Sub

The important code lines are those that use the Goto method. The first jump is to the last cell of the
first row, and the second jump moves back to the true target, Z1. By moving in this way, column Z
ends up just to the right of the frozen range, A:G.

While this works just fine, a better solution would be to use the Scroll parameter with the Goto
method. Consider the following example:

Sub GotoCol2()
With Application
ActiveWindow.FreezePanes = False
Range("H1").Select
ActiveWindow.FreezePanes = True
.Goto Reference:=Range("Z1"), Scroll:=True
End With
End Sub

The Scroll parameter is optional with the Goto method; it defaults to False. If you set it to True,
then Goto scrolls through the window so that the upper-left corner of the target range (Z1) appears
in the upper-left corner of the window.

Flipping Data
How to reverse the order of rows in a table: thus, if you have a table with ten rows, the rows would
go from ten to one instead of one to ten.

There is no intrinsic function in Excel that allows you to flip data in this manner. However, you can
use the sorting capabilities of Excel to accomplish the same thing by following these general steps:

1. Insert a new column immediately to the left of your data table.


2. In the cells of the new column, enter the numbers 1 through however many rows there are in
your table.
3. Select the rows that make up your data table.
4. Choose Sort from the Data menu. Excel displays the Sort dialog box. In the Sort By drop-
down list, indicate you want to sort by your newly created column.
5. Click Descending as the type of sort., then click OK.

If you have to do a lot of data flipping on a daily basis, using the above steps can get rather tiring. In
this case, you may want to create a macro to do the job for you. The following macro, FlipRows,
will do the trick:

Sub FlipRows()
Dim vTop As Variant
Dim vEnd As Variant
Dim iStart As Integer
Dim iEnd As Integer
Application.ScreenUpdating = False
iStart = 1
iEnd = Selection.Rows.Count
Do While iStart < iEnd
vTop = Selection.Rows(iStart)
vEnd = Selection.Rows(iEnd)
Selection.Rows(iEnd) = vTop
Selection.Rows(iStart) = vEnd
iStart = iStart + 1
iEnd = iEnd - 1
Loop
Application.ScreenUpdating = True
End Sub

In order to use this macro, all you need to do is select the rows you want flipped and run it. The
macro will not change your data, other than flipping the rows. In other words, it will not add any
columns of information.

An interesting feature of this approach is that you can quickly adapt it to flipping columns of data.
All you need to do is change all occurrences of the word "Rows" to "Columns." Thus, the following
becomes the new macro:

Sub FlipColumns()
Dim vTop As Variant
Dim vEnd As Variant
Dim iStart As Integer
Dim iEnd As Integer
Application.ScreenUpdating = False
iStart = 1
iEnd = Selection.Columns.Count
Do While iStart < iEnd
vTop = Selection.Columns(iStart)
vEnd = Selection.Columns(iEnd)
Selection.Columns(iEnd) = vTop
Selection.Columns(iStart) = vEnd
iStart = iStart + 1
iEnd = iEnd - 1
Loop
Application.ScreenUpdating = True
End Sub

Again, simply select the columns you want to flip and then run the macro.

Highlighting the Rows of Selected Cells


Sometimes it is easy to lose track of where the selected cell is located in a worksheet. There are
several ways you can locate the cell, but sometimes it would be handy to just have a way to
highlight the whole row of the selected cell.

The easiest way to do this in Excel is to press Shift+Space Bar. The entire row is highlighted, and
the selected cell remains the same. If you want to move to another cell in the same row (without
changing the highlight), you can use Tab to move to the right and Shift+Tab to move to the left.

If you prefer to have Excel automatically highlight the row, you must rely upon a macro. The
following one will do the trick:

Sub Worksheet_SelectionChange(ByVal Target As Excel.Range)


Static rr
Static cc

If cc <> "" Then


With Columns(cc).Interior
.ColorIndex = xlNone
End With
With Rows(rr).Interior
.ColorIndex = xlNone
End With
End If

r = Selection.Row
c = Selection.Column
rr = r
cc = c

With Columns(c).Interior
.ColorIndex = 20
.Pattern = xlSolid
End With
With Rows(r).Interior
.ColorIndex = 20
.Pattern = xlSolid
End With
End Sub

Make sure you attach the macro to the worksheet you are using at the time. All the code does is
highlight the row and column the active cell is at. When moving to another cell, the code
remembers the previous cell (by using variables declared as Static) and removes the highlighting
from the previous rows and columns. This code highlights both the current row and column. For
just highlighting the row, remove the chunks of code with r and rr in them. The only real problem
with this method is that if your sheet has any previous color-filled cells, these will be changed to
NoFill, erasing any color that was there.

Displaying a Set Column Range


Let's say that you want to display a specific number of columns on a worksheet in the available
window space. You can manually figure out the necessary width of each column and do the
adjustments, or you can write a macro that will figure out, proportionally, how the width of each
column should be adjusted to get the desired results.

An easier method, however, is to just adjust the zoom factor for a desired number of columns. This
can be done manually by selecting the columns and then choosing View | Zoom | Fit Selection.

If you want to do it programmatically, it is even easier. Right-click a worksheet tab (the one you
want this macro to apply to) and then choose View Code from the resulting Context menu. Excel
displays the Visual Basic Editor, and you should enter the following into the code window:

Private Sub Worksheet_Activate()


Range("A1:L1").Select
ActiveWindow.Zoom = True
Range("A1").Select
End Sub

This particular macro assumes that you want to view columns A through L in the window. It selects
the range A1:L1, and then sets the zooming factor to display just that selection (the columns you
want). Finally, it selects cell A1 and ends.

FUNZIONE: Finding the Address of the Lowest Value in a Range


When writing a macro, you can find the lowest value in a range of cells by using the
WorksheetFunction method to apply the MIN worksheet function. You may need, however, to not
only find the lowest value in the range, but also the address of the first cell that contains that value.
One simple way is to simply step through the range you want to examine and derive both the lowest
value and the address of the cell being examined, as in the following:

Function FindLowestAddr(pRng As Range) As String


Application.Volatile
MinVal = pRng.Cells(1).Value
MinAddr = pRng.Cells(1).Address
For Each c in pRng
If c.Value < MinVal Then
MinVal = c.Value
MinAddr = c.Address
End If
Next c
FindLowestAddr = MinAddr
End Function

Note that this approach doesn't rely upon the MIN worksheet function at all. There is a drawback to
it, however—it doesn't differentiate between cells that contain numeric values and those that don't.
In other words, if the range passed to the function contains a blank cell, that cell is considered to
contain a zero value, which may very well be the lowest value in the range.

One way around this is to rely upon worksheet functions from within the macro. The following
macro uses both the MIN and MATCH worksheet functions to determine the location of the
minimum value and then the index (offset) of that cell within the range.

Function GetAddr(rng As Range) As String


Dim dMin As Double
Dim lIndex As Long
Dim sAddress As String

Application.Volatile
With Application.WorksheetFunction
dMin = .Min(rng)
lIndex = .Match(dMin, rng, 0)
End With
GetAddr = rng.Cells(lIndex).Address
End Function

It should be noted that if you are using the macro only to discover the address because you figured
there was no way to derive the desired information without the macro, then you can do away with
the macro entirely by using a worksheet formula. For instance, if you want to determine the address
of the lowest-valued cell in the named range MyRange, you could use the following:

=ADDRESS(ROW(MyRange)+MATCH(MIN(MyRange),MyRange,0)-1,COLUMN(MyRange))

Comparing Lists for Duplicates


You have a worksheet that contains lists of part numbers. On one worksheet you have a list of part
numbers, and on another worksheet you have a similar list. The lists are not identical, however, and
you want to determine if a particular part number on one list also appears on the other.

One solution is to somehow combine the lists, but add some sort of indicator as to which original
list the particular part number came from. This approach (or a variation thereon) is, in fact, the
approach taken by many Excel users.
What if you don't want to combine the lists, however? In this case, there is a very easy way to do
the comparison. Follow these steps:

1. Make sure there is a blank column just to the right of each list of part numbers on each
worksheet.
2. Select the part numbers on the first worksheet and give them a name such as "PartList1". (In
Excel 2007 display the Formulas tab of the ribbon and then click on Define Name in the
Defined Names group. In older versions of Excel use Insert | Name | Define.)
3. Select the part numbers on the second worksheet and give them a name such as "PartList2".
4. Assuming that the first part number on the first worksheet is in cell A2, enter the following
formula in cell B2:

=ISNUMBER(MATCH(A2,PartList2,0))
1. Copy the formula down so that a copy appears to the right of each part number on the first
worksheet.
2. Repeat steps 4 and 5 on the second worksheet, but use the following formula:

=ISNUMBER(MATCH(A2,PartList1,0))

When you are done, either TRUE or FALSE will appear to the right of each part number on each
worksheet. If TRUE appears, the associated part number appears on the other worksheet. If FALSE
appears, then the part number is unique and does not appear on the other worksheet.

Another approach is to use an array formula to do the comparisons. You could follow the same
steps shown above, but use the following formula in step 4 (and PartList1 variation in step 6):

=OR(EXACT(A2,PartList2))

Since this is an array formula, you would enter it by using Shift+Ctrl+Enter. The result is the same
TRUE and FALSE designation described above.

Regardless of which formula approach you use, you can use the AutoFilter capabilities of Excel to
limit what is shown on either worksheet. If you filter to show only the FALSEs, you will have a list
of all unique part numbers. If you filter to show TRUEs, then you will have a list of duplicates.

Deleting Duplicate Columns


It is possible that the data in one column will be exactly the same as the data in another column, so
you want to delete any duplicate columns within the worksheet. The first step, of course, is to figure
out if two columns are identical or not. This can be determined rather easily with an array formula
such as the following:
=AND(A1:A100=B1:B100)

(Remember that an array formula is entered by using Shift+Ctrl+Enter.) The formula compares all
the values in the first 100 rows of columns A and B. If they are all the same, then the formula
returns TRUE. If any of the cells don't match, then the formula returns FALSE. If the result is
TRUE you could then delete one of the columns because they are the same.

If you want something that is a bit more automatic, meaning that the duplicate column is deleted,
then you'll need to use a macro. The following steps through all the columns in the worksheet and,
starting with the right-most column, compares all the columns. If any are the same—regardless of
their order in the worksheet—then the macro asks if you want the duplicate column deleted.
Sub DeleteDuplicateColumns()
Dim rngData As Range
Dim arr1, arr2
Dim i As Integer, j As Integer, n As Integer

On Error Resume Next


Set rngData = ActiveSheet.UsedRange
If rngData Is Nothing Then Exit Sub

n = rngData.Columns.Count

For i = n To 2 Step -1
For j = i - 1 To 1 Step -1
If WorksheetFunction.CountA(rngData.Columns(i)) <> 0 And _
WorksheetFunction.CountA(rngData.Columns(j)) <> 0 Then
arr1 = rngData.Columns(i)
arr2 = rngData.Columns(j)
If AreEqualArr(arr1, arr2) Then
With rngData.Columns(j)
'mark column to be deleted
.Copy
If MsgBox("Delete marked column?", vbYesNo) _
= vbYes Then
rngData.Columns(j).Delete
Else
'remove mark
Application.CutCopyMode = False
End If
End With
End If
End If
Next j
Next i

End Sub
Function AreEqualArr(arr1, arr2) As Boolean
Dim i As Long, n As Long
AreEqualArr = False
For n = LBound(arr1) To UBound(arr1)
If arr1(n, 1) <> arr2(n, 1) Then
Exit Function
End If
Next n
AreEqualArr = True
End Function

Stepping Through a Non-Contiguous Range of Cells


Using macros to step through each cell in a selection is a common occurrence. What if that selected
range is made up of non-contiguous cells, however? When it comes to VBA, there is very little
difference between a contiguous selection and a non-contiguous selection. Excel lets you access
each of them the same. Consider the following code snippet:

Dim c As Range

For Each c In Selection


' do something here
MsgBox c.Address & vbTab & c.Value
Next c
In this case the cells in the selected range are stepped through, one at a time, using the For ... Next
loop. Inside the loop the c variable represents an individual cell and can be used in references, as
shown.

If, for some reason, you want to access each contiguous area within the selection, you can do so by
specifically addressing the Areas group, as shown in this snippet:

Dim a As Range
Dim c As Range

For Each a In Selection.Areas


'Now each a refers to a contiguous range
'Do something here with areas, if desired
For Each c In a.Cells
'Now each c refers to a cell in the area
'Do something here
MsgBox c.Address & vbTab & c.Value
Next c
Next a

You should also note that if the range you want to access (contiguous or non-contiguous) has been
named in Excel, you can also access just the cells in the named range. Simply replace the word
"Selection" in each of these examples with name of the range, in this manner:

Dim c As Range

For Each c In Range("MyNamedRange")


' do something here
MsgBox c.Address & vbTab & c.Value
Next c

Selecting Cells of a Specific Color


To accomplishing this task in the worksheet, follow these steps:
1. Press Ctrl+F to display the Find tab of the Find and Replace dialog box.
2. Make sure there is nothing in the Find What box.
3. Click Format. (You may need to click Options to see the Format button.) Excel
displays the Find Format dialog box.
4. Make sure the Patterns tab (Excel 2003) or the Fill tab (Excel 2007) is displayed.
5. From the colors available, choose the color you want to find.
6. Click OK to close the Find Format dialog box.
7. Click Find All. The Find and Replace dialog box expands to show the addresses
of all the cells formatted with the color you specified in step 5.
8. Click one of the cell addresses in the bottom of the dialog box. Excel selects the
cell within the actual worksheet.
9. Press Ctrl+A. All of the addresses within the dialog box are selected.
10. Click Close. All the cells of the desired color are selected.

If you are using Excel 97, Excel 2000, or Excel 2002 the only way to select cells of a particular
color is to use a macro. Consider the macro shown here:

Sub SelectColoredCells()
Dim rCell As Range
Dim lColor As Long
Dim rColored As Range

'Select the color by name (8 possible)


'vbBlack, vbBlue, vbGreen, vbCyan,
'vbRed, vbMagenta, vbYellow, vbWhite
lColor = vbBlue

'If you prefer, you can use the RGB function


'to specify a color
'lColor = RGB(0, 0, 255)

Set rColored = Nothing


For Each rCell In Selection
If rCell.Interior.Color = lColor Then
If rColored Is Nothing Then
Set rColored = rCell
Else
Set rColored = Union(rColored, rCell)
End If
End If
Next
If rColored Is Nothing Then
MsgBox "No cells match the color"
Else
rColored.Select
MsgBox "Selected cells match the color:" & _
vbCrLf & rColored.Address
End If
Set rCell = Nothing
Set rColored = Nothing
End Sub

To use the macro, select a range of cells before running it. The macro then steps through each
selected cell and compares its color with whatever color you specify in lColor. If a match is found,
then the cell is added to a selection set. When completed, the macro selects only those matching
cells, and then exits.
If you would like to find out other macro-based solutions, you can refer to the following article at
the Microsoft Knowledge Base:

http://support.microsoft.com/?kbid=142122

Relative References within Named Ranges


If you give a name to an entire row, e.g. "Sales," then you can use the Sales name in various
formulas. For instance, in any given column you can say =Sales, and the value of the Sales row, for
that column, is returned by the formula.
You can use the same formula technique to refer to cells in different columns in a couple of
different ways.
First of all, you can use the INDEX function to refer to the cells. The rigorous way to refer to the
value of Sales in the same column is as follows:
=INDEX(Sales,1,COLUMN())

This works if the Sales named range really does refer to the entire row in the worksheet. If it does
not (for instance, Sales may refer to cells C10:K10), then the following formula refers to the value
of Sales in the same column in which the formula occurs:
=INDEX(Sales,1,COLUMN()-COLUMN(Sales)+1)

If you want to refer to a different column, then simply adjust the value that is added to the column
designation in the INDEX function. For example, if you wanted to determine the difference
between the sales for the current column and the sales in the previous column, then you would use
the following:
=INDEX(Sales,1,COLUMN()-COLUMN(Sales)+1) - INDEX(Sales,1,COLUMN()-COLUMN(Sales))

The "shorthand" version for this formula would be as follows:


=Sales - INDEX(Sales,1,COLUMN()-COLUMN(Sales))

There are other functions you can use besides INDEX (such as OFFSET), but the technique is still
the same - you must find a way to refer to an offset from the present column.
There is an easier way to get at the desired data, however. Let's say that your Sales range also has a
heading row about it, similar to what is shown in this figure.
The heading row lists the years for the range, and the values under the headings are those that
actually make up the Sales range. To make sure this technique will work, follow these steps:
1. Click the Office button and then click Excel Options. Excel displays the Excel Options
dialog box.
2. Click the Formulas link at the left side of the dialog box.
3. Ensure that the Use Table Names in Formulas check box is selected.
4. Click OK.
With this configuration change done, you can use the following as your formula:
=Sales '2009' – Sales '2004'

What you are actually doing is instructing Excel to work with unions of cells. In this instance, Sales
'2009' returns the cell at the intersection of the Sales range and the '2009' column. A similar union is
returned for the portion of the formula to the right of the minus sign. The result is the subtraction of
the two values you wanted.
TABELLE
Using a Macro to Select a Modified Table Body
One of the big challenges when processing your data using macros is to make sure that you select
all the data (and just the data).

Defined tables are something introduced with Excel 2007. You create them by using the Table tool
on the Insert tab of the ribbon. I normally find it best to enter my column headings and my data, put
any summary formulas in the last column of the table, but don't put them in the last row. I then
select a cell in the table and use the Table tool to define the entire area of the table.

Once a table is defined in this manner, you can then use the Design tab of the ribbon to modify how
Excel sees your table. Click the tab and make sure, in the Table Style Options group, that you
specify your table has a Header Row, Total Row, First Column (for your column headers), and Last
Column (for your summary formulas). You can then use a macro such as the following to figure out
and select the table body:

Sub SelectTableBody()
Dim rTableData As Range

With ThisWorkbook.Worksheets(1)
Set rTableData = .ListObjects("Table1").DataBodyRange
Set rTableData = rTableData.Offset(0, 1) _
.Resize(, rTableData.Columns.Count - 2)
End With

rTableData.Select
End Sub

The first Set statement sets the rTableData range equal to what Excel considers the body of the data
table. This includes everything except the header and the total row. (Why Excel includes the first
column and the last column when you've designed those columns to be special beats me.) The next
Set statement then adjusts the range inward by one column on the left and one column on the right.
The result is that rTableData represents just the data range that you want.

This approach is dynamic in nature, meaning that it will adjust automatically (well, each time you
run it) whenever you add or delete table rows or column. It will not adjust properly if you happen to
delete either the first or last columns of your data table; it assumes those columns will never be part
of the body range you want.

Spreading Out a Table


Sometimes you may get a worksheet from someone else, and you need some room to work on the
information provided. For instance, you may find it helpful to add some blank rows between each of
the original rows in a data table. While this can be done rather easily using the Insert menu, it can
quickly become tedious--particularly if you have a large table that you want to spread out.

The following macro will help you in this situation. All you need to do is select the first row in the
data table. When you run the macro, it asks you how many blank rows you want to insert between
the original rows. When you provide a number, the macro steps through the table and starts
inserting blank rows. The macro stops when the first blank cell after the original table is detected.
Sub SpreadOut()
Dim iBlanks As Integer
Dim J As Integer

iBlanks = InputBox("How many blank rows?", "Insert Rows")


ActiveCell.Offset(1, 0).Select
While ActiveCell.Value > "" And iBlanks > 0
For J = 1 To iBlanks
Selection.EntireRow.Insert
Next J
ActiveCell.Offset(iBlanks + 1, 0).Select
Wend
End Sub

Counting Unique Values


Sometimes you need to know the number of unique values in a range of cells. For instance, suppose
that an instructor was teaching the following classes:

104-120
104-101
104-119
104-120

In this case there are three unique values. There is no intuitive worksheet function that will return a
count of unique values, which makes one think that a user-defined function would be the logical
approach. However, you can use an array formula to very easily derive the desired information.
Follow these steps:

1. Define a name that represents the range that contains your list. (This example assumes the
name you define is MyRange.)
2. In the cell where you want the number of unique values to appear type the following
formula, but don't press Enter yet:

=SUM(1/COUNTIF(MyRange,MyRange))
3. Instead of pressing Enter, press Ctrl+Shift+Enter. This informs Excel that you are entering
an array formula. The formula shown in the formula bar should now appear as follows
(notice the addition of the surrounding braces, indicative of array formulas):

{=SUM(1/COUNTIF(MyRange,MyRange))}

That's it! The cell now contains the number of unique name values in the specified range.
This approach is not case-sensitive, so if you have two values that differ only in their
capitalization (ThisName vs. THISNAME), they are both counted as a single unique value.
In addition, there can be no blank cells in the range. (Having a blank cell returns a #DIV/0
error from the formula.)

If your particular needs require that your list contain blanks (but you don't want them
counted) and you want the evaluation to be case-sensitive, then you must turn to a macro.
The following VBA macro, CountUnique, will do the trick:

Function CountUnique(ByVal MyRange As Range) As Integer


Dim Cell As Range
Dim J As Integer
Dim iNumCells As Integer
Dim iUVals As Integer
Dim sUCells() As String
iNumCells = MyRange.Count
ReDim sUCells(iNumCells) As String

iUVals = 0
For Each Cell In MyRange
If Cell.Text > "" Then
For J = 1 To iUVals
If sUCells(J) = Cell.Text Then
Exit For
End If
Next J
If J > iUVals Then
iUVals = iUVals + 1
sUCells(iUVals) = Cell.Text
End If
End If
Next Cell
CountUnique = iUVals
End Function

Simply put an equation similar to the following in a cell:

=CountUnique(MyRange)

The value returned is the number of unique values, not counting blanks, in the range.

Calculating the Interval Between Occurrences


With a long list of items in a worksheet, you may want to determine the last time a particular item
appeared in the list. For instance, looking at the value in cell A351, the last time that value occurred
in the list was in cell A246. We need a formula that could be placed in cell B351 and return 105, the
difference between 351 and 246.

This approach is difficult to implement in Excel because Excel is not very good at searching
backwards - up a column. If the premise could be reversed, then the task becomes much simpler.
For instance, if a formula in cell B246 could return the value 105, indicating the interval until the
next occurrence of the value in cell A246, instead of calculating the last occurrence. The following
formula calculates the next occurrence of the value in cell A1:

=MATCH(A1,A2:$A$65536,0)

Place this formula in cell B1 and copy it down however many cells are necessary. If the value in
column A does not occur again in the column, then the formula returns the #N/A error. If you would
rather have the formula return 0, then the following works:

=IF(ISNA(MATCH(A1,A2:$A$65536,0)),0,MATCH(A1,A2:$A$65536,0))

If you absolutely must count upwards (find the previous occurrence instead of the next occurrence),
then the easiest way to do it is with a user-defined function. The following function, RowInterval,
will look backward through a range you specify and return the desired interval:

Function RowInterval(TestCell As Range, LookHere As Range) As Long


Dim varValue As Variant
Dim lngRow As Long
Application.Volatile
varValue = TestCell.Value

'Check for occurrences of the test value in the search range


If WorksheetFunction.CountIf(LookHere, varValue) > 0 Then
With LookHere
'Get the last row of the search range
lngRow = .Row + .Rows.Count - 1
'Start with the last cell in the search range and work up
Do Until .Item(lngRow, 1).Value = varValue
lngRow = lngRow - 1
Loop
End With
'Subtract the number of the row containing the found occurrence
'from the number of the row containing the test value
RowInterval = TestCell.Row - lngRow
End If
End Function

In order to use the function, you would put the following formula in cell B2, and then copy the
formula down the number of desired cells:

=RowInterval(A2,A$1:A1)

Tables in Excel
A table is a feature in Excel that makes it easier to
format and analyze a set of data points in a
spreadsheet. Tables were introduced in Excel 2007
as an extension of the ‘Lists’ feature in the earlier
versions. In Excel 2007 onwards, you can also use
the table formulas to extract data from a table.

In Excel 2007 and later, all you have to do to


convert a given range to a table is to simply select
the range and then click the ‘Table’ button under
the ‘Insert’ tab on the ribbon. Better still, use the
shortcut key CTRL + T.

The advantage of using Tables are about:

Formatting: Completely change the look and feel of your data


with a few mouse clicks

Summarize by adding row for Total: Just turn on the check


box for ‘Total Row’ and you have a new row inserted just
below the data set with the totals. Not only totals, you can
select any cell in this row and choose from a number of
aggregation options such as count, min, max etc.

Export and Share: Export and share the table with other users using SharePoint

Provide a Name to the Table: You can give the table a specific name (say ‘Sales_Data’) and use it
later in your formulas. To give a new name to the table, open up the ‘Name Manager’ under the
‘Formulas’ tab and then edit the table name.
Table Formulas let you access table in a easy and intuitive manner. Let’s begin by converting a
range to a table. When you create a new table, Excel will provide with a default name, say
something like ‘Table1′. This may not be most intuitive of names and you may wish to rename it to
something else that is easier to remember and comprehend for others. Open the ‘Design’ tab and
overwrite the text in the ‘Table Name’ box to something like ’sales’.

You can now refer to and use the entire table, individual columns, rows, data range, headers or
totals in your formulas.

Using a Specific Column from the Table in a Formula


Say you wanted to know the average for all items in the ‘Revenue’ column. Enter something like
=AVERAGE(sales[Revenue]) in a cell and smile. The formula is so intuitive that it hardly
needs explaining. The ’sales[Revenue]‘ string refers the data points in the ‘Revenue’ column of the
sales table. ’sales[Target'] would have referred to the ‘Target’ column of the same table. We can
now use this like any other range in any excel formula. So =MAX(sales[Revenue]),
=LARGE(sales[Revenue],5) and =COUNT(sales[Revenue]) are all valid formulas.

Using a Specific Row from the Table in a Formula


What’s good for a column is good for the row. Format, however differ. To refer to a row in a table,
we use the @ symbol. So if you want to refer to the the 10th row in the table, write =sales[@] in
any cell in the 10th row. So something like =countif(sales[@],”<>”) would give you
count of non-blank cells in the particular row of the table. If you copy the same formula to the cell
immediately below, the corresponding values from the next row would be returned - even though
the formula hasn’t changed.

Using the Entire Table in a Formula


What’s good for a column and row must be good for the table
To refer to the entire table, use : =sales[#All]
To refer to only the data portion of the table, use : =sales[#Data]
To refer to the headers, use : =sales[#Headers]

Using the SUBTOTAL Formula with the Table


Another interesting feature of the Table is the use of SUBTOTAL function. The SUBTOTAL
formula has two parts - the first one indicates the formula to use for aggregation and the second one
contains the range to use. So =SUBTOTAL(9,A1:A10) would give the sum of the range from
A1:A10 while =SUBTOTAL(1,A1:A10) would provide the average for the same range.

Coming back the the Excel Table, you can aggregate over the
entire table (or a portion of it) the values by using the
SUBTOTAL formula and providing it with the reference to a
particular row, column or the entire table. Just as in the example
above, you can get the average of the ‘Revenue’ column by
using =SUBTOTAL(1, sales[Revenue]).
If you noticed, when we turned on the ‘Total Row’ option, a new row with the total for columns got
added to the table. We can now go ahead and modify the formulas using any of the formula options
shown above. So the totals are not limited to just being summing but can very well be extended to
averages, min, max, variance etc.

Using the Totals for a Particular Column in a Formula


To refer to the total for a column in the table, say Revenue, we can now write something similar to
=sales[[#Totals],[Revenue]]. Please note that the ‘total’ value returned may not be the
total (SUM) but is determined by the SUBTOTAL function parameter used to aggregate the
column. Let’s illustrate this with an example. If the SUBTOTAL formula in the ‘Total Row’ for the
‘Revenue’ column contained an aggregation function parameter with a value of 4, the total would
have returned maximum value from the column. Now when somebody wants to refer to this total
using =sales[[#Totals],[Revenue]], the “total” returned would not be a sum of column
values but the maximum.
TABELLE PIVOT
Inserire un campo calcolato in una Tabella Pivot
Tra le opzioni meno conosciute delle Tabelle Pivot vi è l'inserimento di un campo che esegua un
calcolo automatico sui dati selezionati. Per esempio, da una tabella in cui si estraggono Fatturato e
Quantità per determinate dimensioni di analisi è possibile calcolare il prezzo medio.
Per richiamare questa opzione si deve attivare la Barra della Tabella Pivot e, dal pulsante Tabella
Pivot, scegliere Formule e Campo Calcolato.
Da qui è possibile inserire formule semplici e complesse usando come variabili i nomi dei campi
della tabella pivot. Per esempio, avendo a disposizione i campi Valore e Quantità potremo calcolare
il prezzo scrivendo:

Valore / Quantità

Per prevenire l'errore #DIV/0! si dovrà scrivere una formula del tipo:

SE(Quantità = 0; 0; Valore / Quantità)

In generale, è possibile usare molte formule di Excel all'interno del campo calcolato, ma non sono
supportate le formule di ricerca e riferimento e le matrici.

Formule dalle Tabelle Pivot


Eseguendo calcoli utilizzando i dati contenuti in una cella appartenente ad una Tabella Pivot., si
ottiene la funzione INFO.DATI.TAB.PIVOT (GETPIVOTDATA in inglese):

=A1*INFO.DATI.TAB.PIVOT("Valore";$A$3;"campo1";"campo2")

La formula è indipendente e, anche modificando la struttura della Pivot, essa mantiene la sua
correttezza.
Purtroppo, però, non è possibile copiare la formula per le altre celle della Pivot e gli utenti di una
versione precedente alla XP vedono questa formula come un errore. Per ovviare a questo
inconveniente è necessario disabilitare la funzione, accedendo al menu Strumenti, scegliendo
Personalizza, Barre degli strumenti, scegliendo la sezione Dati e trascinando il bottone “Genera
InfoDatiTabPivot” in una barra.

Updating Multiple PivotTables at Once


For certain types of data analysis, PivotTables can be very handy. If you have a workbook that
contains several PivotTables, all based on the same data, you may wonder if there is a way to
update them all at once, rather than going through them individually and updating them.

There is no Excel command that allows you to update all PivotTables, but you can create a short
macro that will do the job for you. The following macro, RefreshAllPivots, steps through each
worksheet in a workbook, checks to see if there are any PivotTables, and then updates them if there
are.

Sub RefreshAllPivots()
Dim wks As Worksheet
Dim pt As PivotTable

For Each wks In Worksheets


For Each pt In wks.PivotTables
pt.RefreshTable
Next pt
Next wks
End Sub

If you do a lot of work with multiple PivotTables, you may want to assign the macro to a shortcut
key, the Quick Access toolbar, a toolbar button, or to a menu option so that you can run it easier.

Too Many Rows or Columns in a PivotTable


When attempting to refresh a PivotTable, it is possible to receive the error: 'Excel cannot make this
change because there are too many row or column items.' The message tells to drag at least one row
or column field off the PivotTable and to try again. Problem is, this error just started showing up
with no apparent cause, even if the size of the PivotTable is not changed.

This is a generic error message that basically means "the source data is more than can be handled in
a PivotTable." It probably just started showing up because some internal limit within Excel was
reached. Excel is also limited by the amount of memory available in your system. You may want to
check how much memory you have available and add more memory, if necessary.

The limits of what Excel can stuff into a PivotTable depend on the version of Excel you are using.
The limits are discussed in various Knowledge Base articles. Here is the one for Excel 2000:

http://support.microsoft.com/?kbid=211517

These are the limits for Excel 2002 and Excel 2003:

http://support.microsoft.com/?kbid=820742

As of this writing there is no Knowledge Base article that addresses PivotTable limits in Excel
2007, so it is a good idea to keep the limits for the previous version (Excel 2003) firmly in mind.

Pointing PivotTables to Different Data


Summary: Changing the data source PivotTables go to can be a bit tricky: re-pointing one
PivotTable to a different source workbook only creates a second pivot cache, thereby causing a
much larger PivotTable workbook and a slower response time in Excel.

Assume that File1 is the workbook containing the PivotTables, File2 is the current data source
workbook, and File3 is the new data source workbook. Further, all the PivotTables in File1 share
the same pivot cache which, in turn, points to the data in File2. These are the steps to switch
everything over so File1 finally pointed to File3:

1. Rename the File3 to something else, such as File3Real.


2. Open File1 in Excel.
3. Open File2 in Excel.
4. With File2 displayed, press F12. Excel displays the Save As dialog box.
5. Save the file using the File3 name. Since File1 is also open, Excel automatically repoints the
pivot cache (and hence all the PivotTables in File1) to File3.
6. Close File3.
7. Save and Close File1.
8. Outside of Excel, delete the File3 workbook created in step 5.
9. Rename the File3Real workbook with the name File3.

That's all there is to it; File3 is now the new data source for the PivotTables in File1. As well, any
fields that do not exist in File3 will also be removed from the PivotTable reports when you next
open File1.

Rows in a PivotTable
When working with PivotTables, you may have a need to determine how many rows the PivotTable
contains. There are a couple of ways you can go about this. If you want to use a worksheet formula,
you can create a formula that will return the count of cells. The first thing you need to do is to
determine which column of your PivotTable you want to count. For the sake of this example, let's
say that you want to count column C. Display the New Name dialog box and specify a name for
your data in the Name field. In the Refers To field enter the following formula:

=OFFSET($C$1,0,0,COUNTA($C:$C,1))

Click OK, and you have given a name to a range of data defined by the formula. Assuming that the
name you used was PTRows, you could then use the following formula in a regular cell:

=ROWS(PTRows)

What is returned is the count of the rows in the data range, which represents your PivotTable. If you
want to determine the row count in a macro, the following line will assign the value to the
lRowCount variable:

lRowCount = ActiveSheet.PivotTables("Pivottable1").TableRange2.Rows.Count

This code returns a count of all the rows in the PivotTable, including the page fields. If you want to
omit the page fields and just return the count of the rows in the main PivotTable, you can use this
code instead:

lRowCount = ActiveSheet.PivotTables("Pivottable1").TableRange1.Rows.Count
TEMPO E DATE
Calculating Week-Ending Dates
When working with dates, you may need to figure out all the dates on which weeks end in a given
year. There are two formulas you can use in order to calculate your week-ending dates. Let's
assume, for the sake of this example, that your year is stored in cell A1. You could then figure out
the first Saturday of the year by using this formula in cell A3:

=DATE(A1,1,1)+7-WEEKDAY(DATE(A1,1,1))

This works because the WEEKDAY function returns a value of 1 (Sunday) through 7 (Saturday) for
any date. If you subtract that value from 7, then you have a value of 6 (Sunday) through 0
(Saturday). When you add that value to the DATE value for January 1 of the year, you end up with
the first Saturday of the year.
If you prefer to have your weeks end on Fridays, then the formula needs to change a bit:

=DATE(A1,1,1)+7-(WEEKDAY(DATE(A1,1,1)+1))

Finally, if you prefer to have your weeks end on Sundays, then the formula needs to be like this
one:

=DATE(A1,1,1)+7-WEEKDAY(DATE(A1,1,1),2)

This formula uses a parameter for the WEEKDAY function that calculates weekdays that range
from 1 (Monday) through 7 (Sunday).
Once you have the first week-ending date for the year (in A3), then you can calculate the rest of the
week-ending dates for the year. Place the following formula in cell A4:

=IF(YEAR(A3+7)=$A$1,A3+7,"")

This checks to see if one week past the previous date is still in the year. If it is, then the new date is
returned. If it isn't, then an empty string is returned. If you copy this formula from A4 down through
A55, then you will have all the desired week-ending dates for the year. With the formulas in place,
simply change the year in cell A1 to see how the dates change.
The range A3:A55 provides room for 53 week-ending dates, which is possible for any given year.
Because you used the IF statement in the formula in cells A4:A55, then the very last value (A55)
will be blank if there were only 52 week-ending dates for the year.

Leap Years and Fiscal Periods


A company's fiscal year can end at any time, not just when a calendar year ends. When putting
together a worksheet, you may want to calculate a date that is one year before or after a given date
that represents the end of a fiscal period. This can be done quite easily with any number of
formulas, such as the following:

=DATE(YEAR(D1)-1, MONTH(D1), DAY(D1))

This formula takes a date (cell D1) and subtracts a year from it. Thus, if D1 contains the date
6/30/10, then the formula returns 6/30/09.
This works great in most instances because most months have the same number of days from one
year to the next. There is, of course, one exception—February. If you have a fiscal year that ends in
February, the variable number of days in the month can play havoc with the above formula. If cell
D1 contains 2/28/09, then the formula returns 2/28/08, when the real end of the fiscal period is
2/29/08. Similarly, if cell D1 contains 2/29/08, then the formula returns 3/1/07, which is obviously
not what was intended.

There are a couple of ways you can determine the end of the fiscal period. The first is through the
use of the EOMONTH function. This function is used to return the end of a month a given number
of months in the past or future. For instance, if you wanted to know the last day of the month twelve
months ago, you can use the following formula:

=EOMONTH(D1,-12)

The EOMONTH function is built into Excel 2007. In previous versions of Excel it is part of the
Analysis ToolPak, so you will need to make sure you have it installed and enabled on your system.
(How you do this has been covered in other ExcelTips.)

In some instances you might not want to use EOMONTH. For example, you might be distributing
the workbook to others, and you are not sure if they have the Analysis ToolPak installed on their
system. In such instances you could use the following formula:

=DATE(YEAR(D1)-1, MONTH(D1)+1, 0)

This formula, just like the EOMONTH function, returns the end of the month for exactly one year
ago. Another formula to return the end of month one year ago is as follows:

=D1-365-(DAY(D1)<>DAY(D1-365))

Finding the Previous Work Day


How to return the date of the previous work day, taking into account any holidays?

=WORKDAY(A1,-1,MyHolidays)

The WORKDAY function is used to determine dates for workdays, based upon adjustments that
you specify. The first argument, A1, refers to the cell where the reference date is located. This
information can be obtained in a couple of different ways. You can manually enter the date into cell
A1 or you could use a formula in that cell to signify the date. For instance, you could use the
following simple formula in cell A1 so that it always contains today's date:

=TODAY()

The second part of the formula, -1, says to subtract one day from the date in A1. The third part of
the formula, MyHolidays, refers to a named range containing a list of dates and holidays you want
skipped in determining the previous workday.

The WORKDAY function returns the date of day previous to the date entered in A1, allowing for
any holidays.
Elapsed Days as Years, Months and Days
If you are using Excel to track information about projects, you may want to know the duration of a
given project in years, months, and days. If you have the starting date and the ending date for each
project, you can use the DATEDIF worksheet function to return the information in the desired
manner. For instance, let's assume that you have a starting date in cell E7 and the ending date in cell
F7. You can calculate the difference between the two dates with this very simple use of DATEDIF:

=DATEDIF(E7,F7,"d")

This function returns the number of days between the two dates, provided the date in E7 is less than
or equal to the date in F7. The third argument, "d", causes DATEDIF to return its result in days.
You can also specify months ("m") and years ('y"). For the purposes of this example, however, there
are several other arguments that are particularly helpful: months excluding years ("ym"), days
excluding years ("yd"), and days excluding months and years ("md").

Using these different arguments, you can concoct a formula that will return an answer indicating the
elapsed days as years, months and days. (Because of the length of the formulas in this tip, I've
broken them into separate lines to make them a bit easier to read. This is a single formula, however,
and should be entered as such into Excel.)

=DATEDIF(E7,F7,"y") & " years, " & DATEDIF(E7,F7,"ym") & " months, " &
DATEDIF(E7,F7,"md") & " days "

Note that this formula will always return plural units, as in years, months, and days. For those who
want to be grammatically correct and provide singular units when it is called for, the following
formula will do the trick:

=IF(DATEDIF(E7,F7,"y")=1,DATEDIF(E7,F7,"y")&" year, ",


DATEDIF(E7,F7,"y")&" years, ")&IF(DATEDIF(E7,F7,"ym")=1,
DATEDIF(E7,F7,"ym") &" month, ",DATEDIF(E7,F7,"ym")
&" months, ")&IF(DATEDIF(E7,F7,"md")=1,DATEDIF(E7,F7,"md")
&" day",DATEDIF(E7,F7,"md")&" days")

This works in all instances except when either years, months, or days is zero. To get rid of the
proper unit when it is zero requires an even longer formula:

=IF(DATEDIF(E7,F7,"y")=0,"",IF(DATEDIF(E7,F7,"y")=1,
DATEDIF(E7,F7,"y")&" year, ",DATEDIF(E7,F7,"y")&" years, "))
&IF(DATEDIF(E7,F7,"ym")=0,"",IF(DATEDIF(E7,F7,"ym")=1,
DATEDIF(E7,F7,"ym")&" month, ",DATEDIF(E7,F7,"ym")&" months, "))
&IF(DATEDIF(E7,F7,"md")=0,"",IF(DATEDIF(E7,F7,"md")=0,
DATEDIF(E7,F7,"md")&" day ",DATEDIF(E7,F7,"md")&" days"))

This formula is getting quite long, but it will return only those units for which there is a value.
Thus, instead of returning "0 years, 2 months, 1 day", it will return "2 months, 1 day."

Even this is not a perfect formula, as it will still display the commas between entries in some
situations where they are not warranted. The following megaformula should fix plurals and commas
and get rid of zero entries.

=IF(DATEDIF(E7,F7,"y")=0,"",IF(DATEDIF(E7,F7,"y")=1,
DATEDIF(E7,F7,"y")&"year",DATEDIF(E7,F7,"y")&"years"))
&IF(AND(DATEDIF(E7,F7,"y")<>0,DATEDIF(E7,F7,"ym")<>0),", ","")
&IF(DATEDIF(E7,F7,"ym")=0,"",IF(DATEDIF(E7,F7,"ym")=1,
DATEDIF(E7,F7,"ym")&" month",DATEDIF(E7,F7,"ym")&" months"))
&IF(AND(OR(DATEDIF(E7,F7,"y")<>0,DATEDIF(E7,F7,"ym")<>0),
DATEDIF(E7,F7,"md")<>0),", ","")&IF(DATEDIF(E7,F7,"md")=0,"",
IF(DATEDIF(E7,F7,"md")=1,DATEDIF(E7,F7,"md")&" day",
DATEDIF(E7,F7,"md")&" days"))

Using the WEEKNUM Function


One of the functions provided by Excel 2007 (and in the Analysis ToolPak in previous versions) is
WEEKNUM. This function is used, oddly enough, to return the week number represented by a
particular date. You use the function in this way:

=WEEKNUM(A5,1)

In this instance, A5 contains a date serial number, and the value 1 indicates that WEEKNUM
should assume that all weeks start on a Sunday. If you prefer your weeks to begin on Mondays, then
you can use the value 2 instead.

You should realize that WEEKNUM always considers the first day of any given year to be in the
first week of the year. Thus, it is possible for the above formula to return up to 54 weeks in a year.
How can this be? Let's use the year 2011 as an example. In 2011 January 1 falls on a Saturday. As
far as WEEKNUM is concerned, this is in the first week of the year. Now, January 2 for that year
falls on a Sunday. Since WEEKNUM believes that every Sunday starts a new week, the second day
of the week is considered in the second week of the year.

This is fine, until you get to the end of the year. The fifty-second week of 2011 ends (according to
WEEKNUM) on December 24, and the fifty-third week begins on December 25 (a Sunday).

An even more interesting scenario is when the year begins on a Saturday and the year is a leap year.
This happened in the year 2000. In that instance, the fifty-third week began on December 24, and
the fifty-fourth week began on December 31.

The Last Business Day


When developing a worksheet, you may have a need to know the last business day of a given
month. Assuming that your business days run Monday through Friday, the following formula will
return the desired date:

=DATE(YEAR(A1),MONTH(A1)+1,0)-(MAX(0,WEEKDAY
(DATE(YEAR(A1),MONTH(A1)+1,0),2)-5))

This formula returns a date that is only a Monday through Friday, and always the last such day in
the month represented by the date in A1. For some purposes, you may need to know what the last
Friday of any given month is. This is easily determined with this formula:

=DATE(YEAR(A1),MONTH(A1)+1,0)-WEEKDAY(DATE
(YEAR(A1),MONTH(A1)+1,0))+(WEEKDAY(DATE
(YEAR(A1),MONTH(A1)+1,0))>5)*7-1

This formula calculates the last day of the month for the date in cell A1 and, based on what day of
the week that date is, subtracts the appropriate number of days to return the previous Friday.
If you want to take business holidays into account, then the complexity of the formula gets quite
high, quite quickly. Because of that, it is best to create a user-defined function (a macro) that will
determine the last business day and compensate for holidays.

The following macro returns a date, Monday through Friday, that represents the last business day.
The date is compared against a holiday list (HolidayList), which should be a named range in your
workbook. If the date is found to be a holiday, then the ending business day is decremented until a
suitable day is located.

Function LastWorkDay(lRawDate As Long, _


Optional rHolidayList As Range, _
Optional bFriday As Boolean = False) As Long

LastWorkDay = DateSerial(Year(lRawDate), _
Month(lRawDate) + 1, 0) - 0
If bFriday Then
LastWorkDay = MakeItFriday(LastWorkDay)
Else
LastWorkDay = NoWeekends(LastWorkDay)
End If

If Not rHolidayList Is Nothing Then


Do Until myMatch(LastWorkDay, rHolidayList) = 0
LastWorkDay = LastWorkDay - 1
If bFriday Then
LastWorkDay = MakeItFriday(LastWorkDay)
Else
LastWorkDay = NoWeekends(LastWorkDay)
End If
Loop
End If
End Function
Private Function myMatch(vValue, rng As Range) As Long
myMatch = 0
On Error Resume Next
myMatch = Application.WorksheetFunction _
.Match(vValue, rng, 0)
On Error GoTo 0
End Function
Private Function NoWeekends(lLastDay As Long) As Long
NoWeekends = lLastDay
If Weekday(lLastDay) = vbSunday Then _
NoWeekends = NoWeekends - 2
If Weekday(lLastDay) = vbSaturday Then _
NoWeekends = NoWeekends - 1
End Function
Private Function MakeItFriday(lLastDay As Long) As Long
MakeItFriday = lLastDay
While Weekday(MakeItFriday) <> vbFriday
MakeItFriday = MakeItFriday - 1
Wend
End Function

Notice that there are three private functions that are included. These functions are called from
within the main LastWorkDay function. The first one, myMatch, is a "wrapper" for the regular
Match method. This usage is included because of the required error handling.

The second function, NoWeekdends, is used to back a date up to the previous Friday if it just
happens to be a Saturday or Sunday. The MakeItFriday function is used to ensure that a date will
always be a Friday.
To use this user-defined function from your worksheet, you use it in a formula, like this:

=LastWorkDay(A1, HolidayList, TRUE)

The first parameter (A1) is the date to be evaluated. The second parameter (HolidayList) is an
optional list of holiday dates. As shown here, it is assumed that HolidayList is a named range in the
worksheet. If this parameter is provided, then the function makes sure that any date it returns is not
on the list of dates in HolidayList.

The final parameter is also optional; it can be either TRUE or FALSE. (The default, if it is not
specified, is FALSE.) If this parameter is set to TRUE, then the function always returns the last
Friday of the month. If this parameter is TRUE and the HolidayList is provided, then the function
returns the last non-holiday Friday of the month.

Converting UNIX Date/Time Stamps


If you import information generated on a UNIX system, you may need to figure out how to change
the date/time stamps to something that Excel can recognize and work with. The conversion is easy,
once you understand the way in which the date/time stamps are figured. Time stamps in UNIX are
stored as an integer value representing the number of seconds since 1 January 1970. Further, time
stamps are stored in GMT time, meaning there has been no adjustment to the stamp to reflect time
zones or time-zone variations (such as Daylight Savings Time).

Excel, on the other hand, stores time stamps as a real number representing the number of days since
1 January 1900 (the default setting). The integer portion of the time stamp represents the number of
full days, while the portion of the time stamp to the right of the decimal point represents the
fractional portion of a day, which can be converted to hours, minutes, and seconds.

To do a straight conversion of a UNIX time stamp to the Excel system, all you need to do is use this
formula:

=UnixTime / 86400 + 25569

In this example, UnixTime can be either a named cell containing the integer UNIX time stamp
value, or it can be replaced with the actual integer value. Since the UNIX time stamp is stored as
seconds, the division by 86400 is necessary to convert to days, which is used by Excel. (86400 is
the number of seconds in a day.) You then add 25569, which is the number of days between 1
January 1900 and 1 January 1970. (It is the value returned if you use the =DATE(1970,1,1)
function.)

Remember, that this does a straight conversion. You may still need to adjust for time zones. If the
UNIX system recorded something occurring at 5:00 pm local time, you need to determine how
many hours difference there is between you and GMT. If there happens to be four hours, then you
need to adjust your conversion formula accordingly, as shown here:

=UnixTime / 86400 + 25569 - 4 / 24

If you are unsure of how your time zone relates to GMT, you can find the needed information here:

http://tycho.usno.navy.mil/zones.html
Using Excel for Timing
You may want to use Excel to record the elapsed time for different events. There are two ways that
this can be approached: either native, within Excel, or with a macro.

If you don't want to use a macro, you can easily set up three columns for your timing. The first
column can be used to record the start time, the second column the end time, and then the third
column the elapsed time (calculated by using a formula that subtracts the start time from the end
time). In order to record times, you select a cell in either the start time or end time columns and
press Ctrl+: (the colon). Excel enters the current time in that cell.

If you want to use a macro that simply returns the elapsed time, then you can use the following:

Public Sub TimeIt()


Dim vStartTime As Date

vStartTime = Time
MsgBox Prompt:="Press the button to end the timing" & vbCrLf _
& "Timing started at " & Format(vStartTime, "hh:mm:ss"), _
Buttons:=vbOKOnly, _
Title:="Time Recording Macro"
ActiveCell.Value = Time - vStartTime
End Sub

This macro records a start time (in vStartTime), and then displays a message box. When you click
on the message box button, the difference between the current time and the start time is stored in the
current cell. (You need to make sure the current cell is formatted with one of the time formats.)

The above macro works very well for recording short events during which you don't need to use
Excel for other tasks. If you need to record longer events, then a different approach is in order. The
following macros work in tandem. The first one records a start time; that is all it does. The second
one uses that recorded time to calculate an elapsed time which is placed in the currently selected
cell.

Global vStTime

Sub StartTiming()
vStTime = Time
End Sub

Sub EndTiming()
ActiveCell.Value = Time - vStTime
End Sub

You could easily assign these two macros to the Quick Access toolbar or to different toolbar buttons
that would, respectively, start and stop the timing process.

Finding the Date Associated with a Negative Value


When working with data taken from the real world, you often have to determine which certain
conditions were met, such as when a particular reading dropped below a certain value. This tip
examines how you can easily tell the date on which a reading drops below zero.

There are a number of ways that this problem can be approached. All of the methods presume that
the dates in column A are in ascending order and that the readings in column B are not in any type
of discernable order. (In other words, the readings could bounce above and below 0 on any given
date.)

Provided that you have some control over the layout of the worksheet, you could add an
intermediate work column in column C, used to indicate when a value is negative. Simply place a
formula like this in column C, to the right of each reading:

=IF(B1<0,A1,"")

This formula returns the date in column A if the value in B is below 0 (negative), otherwise it
returns nothing. All you then need to do is look for the minimum value in column C:

=MIN(C:C)

Format the result as a date, and it represents the date at which the readings first became negative.

Another approach is to forego the use of the intermediate column and use an array formula to
determine the date. Assuming the data is in the range A1:B42, you can use any of the following
formulas:

=MIN(IF(B1:B42<0,A1:A42,""))
=OFFSET($A$1,MATCH(TRUE,$B$1:$B$42<0,0)-1,,,)
=INDEX(A:A,MIN(IF(B1:B42<0,ROW(B1:B42))))
=INDEX(A1:A42,MATCH(TRUE,B1:B42<0,0))
=INDIRECT("A"&MIN(IF(B1:B42<0,ROW(B1:B42))),TRUE)

Remember that these are all array formulas, so you need to enter whichever one you choose by
pressing Shift+Ctrl+Enter. Format the result as a date, and it is the answer you seek.

If you prefer, you could also use a simple macro to determine the date:

Function GetFirstNegative(rngdata)
Dim c As Variant

For Each c In rngdata


If c < 0 Then
GetFirstNegative = c.Offset(0, -1)
Exit Function
Else
GetFirstNegative = "All Data is Positive"
End If
Next
End Function

In your worksheet, you would use this user-defined function in this manner:

=GetFirstNegative(B1:B42)

Specifying Different Weekends with NETWORKDAYS


The NETWORKDAYS worksheet function can be used to easily determine the number of work
days (Monday through Friday) within a range of dates. If your workweek consists of different days
(e.g, only Sunday counts as a non-work day), however, the NETWORKDAYS function may not be
the best place to start.
You can determine this by using a formula based on the NETWORKDAYS function. Assuming
that the starting date is in A1 and the ending date is in B1, the following formula examines the days
between the two dates and essentially return a count of non-Sunday days in that range:

=NETWORKDAYS(A1,B1)+SUMPRODUCT(--(WEEKDAY
(ROW(INDIRECT(A1&":"&B1)))=7))

Of course, since Sundays are the only day of the week being excluded, you could simply skip the
use of NETWORKDAYS and use SUMPRODUCT to figure out if the day should be counted or
not:

=SUMPRODUCT(--(WEEKDAY(ROW(INDIRECT(A1&":"&B1)))>1))

If you expect that there may be holidays in the range, and that those holidays are in the named range
"holidays," then you'll need to go back to using NETWORKDAYS in the formula:

=NETWORKDAYS(A1,B1,holidays)+SUMPRODUCT(--
(WEEKDAY(ROW(INDIRECT(A1&":"&B1)))=7),--
(NOT(ISNUMBER(MATCH(ROW(INDIRECT(A1&":"&B1))
,holidays,0)))))

Other variations of what constitutes the work days in a week have been covered by Chip Pearson at
his site:

http://www.cpearson.com/excel/betternetworkdays.aspx

Adjusting Date Values by Keypress


In a Quicken date field, if you press the plus or minus key the date increments or decrements by one
day. How to create this same sort of effect in Excel? This is a harder problem to approach than one
might assume, particularly in Excel. Since an action needs to be taken upon the pressing of a
particular key (in this case, the plus or minus keys), one would naturally assume that the OnKey
method could be used. Consider the following examples:
Sub Start_OnKey()
Application.OnKey "{+}", "Plus1"
Application.OnKey "-", "Minus1"
End Sub
Sub End_OnKey()
Application.OnKey "{+}"
Application.OnKey "-"
End Sub
Sub Plus1()
If IsDate(ActiveCell) And Not ActiveCell.HasFormula Then
ActiveCell.Value = ActiveCell.Value + 1
End If
End Sub
Sub Minus1()
If IsDate(ActiveCell) And Not ActiveCell.HasFormula Then
ActiveCell.Value = ActiveCell.Value - 1
End If
End Sub

According to all the VBA documentation, the above should work just fine, once you run the
Start_OnKey macro. Every time a plus or minus key is pressed, the appropriate procedure is run to
either increment the date or decrement the date. The problem is, it won't work on some versions of
Excel. Why? Because the plus key, when pressed, apparently puts some versions of Excel into a
special "formula entry" mode that bypasses the normal keyboard buffer relied upon by OnKey. So
while pressing the minus key while a cell containing a date is selected produces the desired result,
pressing the plus key does not.

For those versions of Excel where the plus key is a problem, the only solution is to change the
keystrokes to something else. For instance, you could change the keypresses so that Ctrl+u is used
to increment the date and Ctrl+d is used to decrement the date:

Sub Start_OnKey()
Application.OnKey "^u", "Plus1"
Application.OnKey "^d", "Minus1"
End Sub
Sub End_OnKey()
Application.OnKey "^u"
Application.OnKey "^d"
End Sub

Converting Coded Dates into Real Dates


Sometimes the format in which you receive data is not the same format that would be optimal for
Excel. For instance, you might receive some data that shows dates in a strange format, such as
"04A09", where the first two digits are the day, the letter in the middle is the month (A is January,
B is February, C is March, etc.), and the last two digits are the year. The biggest thing that makes
this date format non-standard is the use of the alphabetic character for the month. So, the first thing
to do is to figure out how to convert that character into a numeric month. This is where the CODE
function can be helpful; it returns the ASCII code for the character. The letter A returns the value
65, B returns 66, and so on. So, all you need to do to convert the letters into the numbers 1 through
12 is to use something like this:
=CODE(UPPER(MID(A1,3,1)))-64

The UPPER function is used to convert the month character to uppercase, just in case the code
allows lowercase letters for months.

Another way of converting the months is to use the FIND function, in this manner:

=FIND(UPPER(MID(A1,3,1)),"ABCDEFGHIJKL",1)

This technique finds the character within the alphabetic string and returns the offset within that
string, 1 through 12.

Either method of converting the months can then be used inside a DATE function to return a date
based upon a year, month, and day. This example uses the CODE method, but you could just as
easily use the FIND method:

=DATE(2000+RIGHT(A1,2),CODE(UPPER(MID(A1,3,1)))-64,LEFT(A1,2))

If there is the possibility that the coded dates could include some dates prior to 2000, then using the
DATEVALUE function to put together the date will produce more accurate results:

=DATEVALUE(CODE(UPPER(MID(A1,3,1)))-64&"/"&LEFT(A1,2)&"/"&RIGHT(A1,2))

If you use the DATEVALUE approach, understand that the formula returns a date serial number
and that you will need to format the cell to display the date as you would like it displayed.
Date for Next Wednesday
You have a date in cell A1 and would like to calculate the date of the following Wednesday in cell
B1. There are actually many formulas you can use, and the one you pick is pretty much up to you.
Here is a good representative sampling of formulas you can use:

=IF(WEEKDAY(A1)<=4,A1+4-WEEKDAY(A1),A1+11-WEEKDAY(A1))
=A1+WEEKDAY(A1, 1)+CHOOSE(WEEKDAY(A1, 1), 2, 0, -2, -4, 1, -1, -3)
=A1+CHOOSE(WEEKDAY(A1),3,2,1,0,6,5,4)
=A1-MOD(WEEKDAY(A1)-5,7)+6
=A1+MOD(4-WEEKDAY(A1),7)

These formulas return a date that represents next Wednesday, provided that the date in cell A1 isn't
a Wednesday to begin with. For instance, if the date in A1 is 5/26/10 (a Wednesday), then each of
these will return 5/26/10. However, if the date is 5/27/10 then the formula returns 6/2/10.

If you want a formula that will return the next Wednesday even when the starting date is a
Wednesday, then you should rely on a different formula. Choose from one of these:

=A1+IF(WEEKDAY(A1,1)=4,7,IF(WEEKDAY(A1,1)<4,4-WEEKDAY(A1,1),11-WEEKDAY(A1,1)))
=IF(WEEKDAY(A1)<4,A1+4-WEEKDAY(A1),A1+11-WEEKDAY(A1))
=IF(WEEKDAY(A1)=4,A1+7,A1+MOD(4-WEEKDAY(A1),7))
=A1+MOD(4-WEEKDAY(A1),7)+7*(0=MOD(4-WEEKDAY(A1),7))
=A1+7-MOD(4+WEEKDAY(A1,2),7)
=A1+4-WEEKDAY(A1)+IF(WEEKDAY(A1)<4,0,7)
=A1+CHOOSE(WEEKDAY(A1),3,2,1,7,6,5,4)
=A1+(7-MOD(WEEKDAY(A1,3)-2,7))
=A1+4-WEEKDAY(A1)+7*(WEEKDAY(A1)>=4)
=A1-MOD(WEEKDAY(A1)-4,7)+7
=A1+4+((WEEKDAY(A1)>=4)*7)-WEEKDAY(A1)
=A1+MOD(10-WEEKDAY(A1),7)+1
=A1+IF(WEEKDAY(A1) < 4,4,11)-WEEKDAY(A1)
=CEILING(A1-4,7)+4
=A1+6-MOD(A1+2,7)

It should be noted that the last two of these formulas works just fine on the PC but won't work as
expected on the Mac. This is because the basis date used for date serial numbers is different on the
Mac than it is on the PC, and thus the computations—which operate on the underlying serial
numbers for the dates—return different values on each platform.

Calculating Averages by Date


Suppose that you have a huge worksheet that contains all the rainfall readings for a given locale for
the past hundred years or so. In cells A2:A37987 you have the dates, 1 January 1903 through 31
December 2006. In cells B2:B37987 you have the measurements for each date. Further, some of the
measurements can be zero (if there is no rainfall for the day) or blank (if no reading was taken that
particular day). With all this information, you want to calculate the average historic rainfall for any
given day of the year.

One solution involves the use of array formulas, as detailed here:

1. Select all the cells in column A that contain dates, and assign this range the name Dates.
2. Select all the cells in column B that contain rainfall data, and assign this range the name
Rainfall.
3. In column D, starting in cell D2, place all the days of the year. You should end up with D2
through D366 filled with dates.
4. In cell E2, enter the following array formula (terminate the formula by pressing
Shift+Ctrl+Enter). The result of the formula is the sum of all the cells in the Rainfall range,
for the date specified in cell D2.

=SUM((MONTH(Dates)=MONTH(D2))*(DAY(Dates)=DAY(D2))*Rainfall)
5. In cell F2, enter the following array formula (terminate the formula by pressing
Shift+Ctrl+Enter). The result of the formula is the number of cells in the Rainfall range,
for the date in cell D2, that have a value in them.

=SUM((MONTH(Dates)=MONTH(D2))*(DAY(Dates)=DAY(D2))*(Rainfall<>""))
6. In cell G2, enter the following regular formula. This is your average for the date in cell D2.

=IF(F2<>0,E2/F2,"")
7. Select the range E2:G2 and copy down for all the dates shown in column D.

This approach works, but it takes quite a while to calculate. This is because you effectively entered
730 array formulas, each checking over 37,000 cells. This is a lot of work, and consequently it may
appear like your machine has "hung" after you complete step 7. It has not hung; it will just take it a
while to complete the calculations.

To decrease the number of calculations that must be performed, you can use a variation on the
above steps. Follow steps 1 through 3, as noted, and then place the following array formula into cell
E2:

=AVERAGE(IF(ISNUMBER(Dates)*ISNUMBER(Rainfall)*(MONTH(Dates)=MONTH(D2))*(DAY(Dat
es)=DAY(D2)),Rainfall))

You can then copy the formula down for all the dates shown in column D. The result of this formula
is the actual average rainfall, the same as had been shown in column G in the previous approach.

This formula works because of the way that Boolean arithmetic works in Excel. The ISNUMBER
function returns either True or False, and the comparisons (MONTH and DAY) return either True
or False. These results are all multiplied against each other, resulting in True only if all the
individual tests are True. Only if they are all True will the average of the Rainfall for that particular
date be calculated.

You can reduce the calculation overhead even further by simply getting rid of all the table that
calculates the averages for every day of the year. With your dates in rainfall in columns A and B,
follow these steps:

1. Select all the cells in column A that contain dates, and assign this range the name Dates.
2. Select all the cells in column B that contain rainfall data, and assign this range the name
Rainfall.
3. In cell D2, place the date for which you want to check the average rainfall. (The year isn't
important; only the month and day are used in the calculation.)
4. Enter the following formula into cell E2:

=AVERAGE(IF(ISNUMBER(Dates)*ISNUMBER(Rainfall)*(MONTH(Dates)=MONTH(D2))*(DAY(Dat
es)=DAY(D2)),Rainfall))

That's it. Now, you can change the date in cell D2 as desired, and cell E2 will always indicate the
average rainfall for that date. The formula in cell E2 is the same as the formula used in the last
approach; the difference is that you aren't calculating it for all the days in a year, and thus the
calculation is done much quicker.

Another approach involves the use of Excel's filtering capabilities. Before you can use them
properly, however, you must create a column that shows only the month and day for each date in
your data. Use this formula in cell C2:

=MONTH(A2) & "-" & DAY(A2)

Now, turn on AutoFiltering (Data | Filter | AutoFilter or, in Excel 2007, the Data tab on the ribbon |
Sort & Filter group | Filter) and use the drop-down list at the top of the new column to select the
date for which you want an average. You then use the following formula, placed in any cell desired,
to show the average rainfall for the selected date:

=SUBTOTAL(1,B:B)

Entering Large Time Values


If you format a cell for elapsed time (using a custom display format of [h]:mm:ss), then Excel
allows you to enter hours, minutes and seconds into that cell. For instance, you could simply enter
129:14:30 to signify 129 hours, 14 minutes, and 30 seconds. You run into a problem, however, if
you try to enter very large time values into the cell. When you try to enter time values in excess of
10000 hours, as in 12721:52:45, then Excel won't parse the entry as a time, but treats it as text.
The interesting thing is that when a cell is formatted for elapsed time using [h]:mm:ss, the cell can
easily display elapsed times that have more than 10000 hours. Thus, you can sum a range of cells to
result in a value more than 10000 hours, but you cannot enter a larger value.
Unfortunately, there seems to be no way around this in Excel. The best solution, however, might be
to rethink how the data is entered. After all, 10000 hours is equal to 416 days and 16 hours—well
over a year. You could easily create a column for entering days, and use another for partial days. A
third column could then use a formula to return the elapsed hours based on the other two columns.
Another solution is to simply not rely on Excel to do the parsing of your input. If you have a huge
number of hours to enter (such as 32315), then you could enter the following in the cell:

=32315/24

Excel maintains what you enter as a formula, but displays the proper number of hours, minutes, and
seconds. If you want to get more precise, you can enter a fractional amount that represents the
portion of an hour represented by your time. For instance, 37 minutes and 15 seconds is 0.620833 of
an hour. Thus, you could enter the hours as follows:

=32315.620833/24

Of course, entering times in this manner can get tedious, particularly when you have calculate the
fractional portion of an hour represented by minutes and seconds. To overcome this, you could
create a custom function that allows you to enter hours, minutes, and seconds, and returns a value
that is easily formatted using the elapsed time format. The following function will do the trick:

Public Function RealBigTime(hr As Double, _


min As Double, sec As Double) As Double
Dim hr1 As Double
Dim min1 As Double
Dim sec1 As Double

Application.Volatile
hr1 = hr / 24
min1 = min / 24 / 60
sec1 = sec / 24 / 60 / 60
RealBigTime = hr1 + min1 + sec1
End Function

After creating the function, enter something like =RealBigTime(32341,30,45) in a cell. The result is
a value that can be formatted with the elapsed time format to 32341:30:45.
TESTO E STRINGHE
Extracting a Pattern from within Text
If you have a large amount of data in a worksheet and you want to extract information from the text
that meets certain criteria, there are several ways that you can approach this problem, and the
correct solution for your needs will depend on the characteristics of the data with which you are
working. If you know that the only place in your data that you will have a dash is within your
pattern, then you can key off of the presence of the dash by using a formula such as the following:

=MID(A1,FIND("-",A1)-2,8)

This finds the dash and then grabs the eight characters beginning two characters to the left of the
dash. This obviously will not work if there are dashes in other places in the text or if it is possible to
have "patterns" that include non-digits (such as 12-34B32) and you want those excluded. In that
case you'll need a much more complex formula:

=IF(ISERROR(INT(MID(A1, FIND("-", A1, 1)-2, 2)) & INT(MID(


A1, FIND("-", A1, 1)+1, 5))), "", MID(A1, FIND("-", A1)-2, 8))

This includes an error checking component that finds out if the characters just before the dash and
just after the dash contain anything other than digits. If they do, then nothing is returned.

The one thing that these formulaic approaches don't do is handle those situations where there may
be more than one occurrence of the pattern within the same cell. In that case, a macro is the best
approach. The following will extract the valid patterns and place them in a new worksheet called
"Results".

Sub ExtractPattern()
On Error Resume Next
Set SourceSheet = ActiveSheet
Set TargetSheet = ActiveWorkbook.Sheets("Results")
If Err = 0 Then
Worksheets("Results").Delete
End If
Worksheets.Add
ActiveSheet.Name = "Results"
Set TargetSheet = ActiveSheet
Cells(1, 1).Value = "Found Codes"
Cells(1, 1).Font.Bold = True
iTargetRow = 2

SourceSheet.Select
Selection.SpecialCells(xlCellTypeLastCell).Select
Range(Selection, Cells(1)).Select

For Each c In Selection.Cells


If c.Value Like "*##-#####*" Then
sRaw = c.Value
iPos = InStr(sRaw, "-")
Do While iPos > 0
If iPos < 3 Then
sRaw = " " & sRaw
iPos = iPos + 2
End If
sTemp = Mid(sRaw, iPos - 2, 8)
sRaw = Mid(sRaw, iPos + 6, Len(sRaw))
If sTemp Like "##-#####" Then
TargetSheet.Cells(iTargetRow, 1) = sTemp
iTargetRow = iTargetRow + 1
Else
sRaw = Mid(sTemp, 4, 5) & sRaw
End If
iPos = InStr(sRaw, "-")
Loop
End If
Next c
End Sub

Note that the macro uses the Like function in two places. The first instance determines if the pattern
occurs anywhere in the cell, and the second instance is used to determine if the extracted characters
exactly match the desired pattern.

FUNZIONE: Converting Numbers to Strings


The use of the Str() function can give bad results for some subroutines. Instead, you should create
a function that returns a stripped-down version of the string:

Function ToNum(X as Variant) as String


Dim A as String

A = Trim(Str(X))
ToNum = A
End Function
The reason that the value passed to the VBA function (X) is defined as a Variant is that you can
then pass any type of numeric value.

Creating a String of repeating characters in a Macro


What do you do if you need a string of 80 equal signs or 25 spaces in your macro? Use the String
function. This function is used to create strings of repeating characters. Consider the following
examples:

sNew1 = String(25, 32)


sNew2 = String(25, " ")
sNew3 = String(80, "=")
sNew4 = String(20, "=*")

The first and second lines are functionally the same; they both produce a line of 25 spaces. In the
first example, the ANSI value of 32 is used, which is the character code for a space. In the third
line, sNew3 will be equal to 80 equal signs.

The fourth line produces a 20-character string of equal signs. This can be a bit frustrating to
programmers familiar with other implementations of BASIC, as to them the last example should
create a 40-character string of alternating equal signs and asterisks. (Under older versions of
BASIC, the String function concatenates whatever you designate, so one could expect this to create
a 40-character string made up of 20 iterations of "=*". Not so; VBA does not implement the String
function as is done in other BASICs.)
Cleaning Text
Excel includes an interesting worksheet function whose duty it is to make sure that your text is
"clean." By this, Excel means that your text contains only printable characters. Thus, the function
removes certain non-printable characters and control codes from your text. The syntax is rather
simple, as follows:

=CLEAN(text)

All you need to do is include the text, or a reference to a cell that contains text. In doing some
testing, it appears that the function removes anything with an ANSI value of 1 through 31, as well
as the values 129, 141, 143, 144, and 157.

You can create your own version of the CLEAN worksheet function that, instead of simply
removing non-printing characters, replaces them with spaces. Consider the following example
macro:

Function ReplaceClean(sText As String, Optional sSubText As String = " ")


Dim J As Integer
Dim vAddText

vAddText = Array(Chr(129), Chr(141), Chr(143), Chr(144), Chr(157))


For J = 1 To 31
sText = Replace(sText, Chr(J), sSubText)
Next
For J = 0 To UBound(vAddText)
sText = Replace(sText, vAddText(J), sSubText)
Next
ReplaceClean = sText
End Function

You use this function in the following manner within your worksheet:

=ReplaceClean(B14)

In this case, all non-printing characters in cell B14 are replaced with a space. If you want the
characters replaced with something else, just provide the text to replace with. The following
example replaces the non-printing characters with a dash:

=ReplaceClean(A1,"-")

The following usage simply removes the non-printing characters, the same as the CLEAN function:

=ReplaceClean(A1,"")

If you look back at the ReplaceClean macro presented earlier, you see that it uses the Replace
function. This VBA function is not available in all the versions of VBA used with the different
versions of Excel. If you try the macro and you get an error on one of the lines that use the Replace
function, then use this version of the ReplaceClean macro instead:

Function ReplaceClean(sText As String, Optional sSubText As String = " ")


Dim J As Integer
Dim vAddText
Dim aWF As WorksheetFunction
Set aWF = Application.WorksheetFunction

vAddText = Array(Chr(129), Chr(141), Chr(143), Chr(144), Chr(157))


For J = 1 To 31
sText = aWF.Substitute(sText, Chr(J), sSubText)
Next
For J = 0 To UBound(vAddText)
sText = aWF.Substitute(sText, vAddText(J), sSubText)
Next
ReplaceClean = sText
Set aWF = Nothing
End Function

Pulling Apart Cells


You can easily use the Text to Columns feature in Excel to pull your data apart. Just follow these
steps:

1. Select the range of cells you want to split.


2. Choose Text to Columns from the Data menu. (In Excel 2007 choose Text to Columns from
the Data tab of the ribbon.) Excel starts the Convert Text to Columns Wizard.
3. Choose whether the text you have selected is fixed width or delimited. (In the case of a
space between first and last name, the text would be delimited.)
4. Click on Next.
5. Specify the delimiters you want Excel to recognize. In the case of pulling apart names, you
should make sure that you use spaces as delimiters.
6. Click on Finish.

Excel pulls apart the cells in your selected range, separating all the text at the delimiter you
specified. Excel uses however many columns are necessary to hold the data.

If you don't want to spread your data completely across the columns, then you will need to use a
macro. For instance, if a cell contains "John Davis, Esq.", then using the Text to Columns feature
will result in the data being spread into three columns: the first containing "John", the second
containing "Davis," (with the comma), and the third containing "Esq." If you would rather have the
data split into two columns ("John" in one and "Davis, Esq." in the other, then the following macro
will be helpful:

Sub PullApart()
Dim FirstCol As Integer, FirstRow As Integer
Dim RowCount As Integer
Dim ThisRow As Integer
Dim j As Integer, k As Integer
Dim MyText As String

FirstCol = ActiveWindow.RangeSelection.Column
FirstRow = ActiveWindow.RangeSelection.Row
RowCount = ActiveWindow.Selection.Rows.Count

For j = 1 To RowCount
ThisRow = FirstRow + j - 1
MyText = Cells(ThisRow, FirstCol).Text
k = InStr(MyText, " ")
If k > 0 Then
Cells(ThisRow, FirstCol + 1).Value = Mid(MyText, k + 1)
Cells(ThisRow, FirstCol).Value = Left(MyText, k - 1)
End If
Next j
End Sub
This macro examines each cell and leaves everything up to the first space in the selected cell, and
moves everything after the space into the column to the right. The only "gottcha" with this macro is
to make sure you have nothing in the column to the right of whatever cells you select when you run
it.

Delimited Text-to-Columns in a Macro


The Text-to-Columns tool can be set to recognize characters within the cells and use those
characters to trigger where the split should take place. This type of splitting is referred to as a
delimited split:

Sub ExampleSplit1()
Selection.TextToColumns _
Destination:=Range("A2"), _
DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, _
ConsecutiveDelimiter:=False, _
Tab:=True, _
Semicolon:=False, _
Comma:=False, _
Space:=False, _
Other:=True, _
OtherChar:="-"
End Sub

Notice all the variables that you can set for the TextToColumns method. Most of these variables are
only necessary because this is a delimited split; the variables set what is used as a delimiter by the
method. Beginning with the Tab line, the variables correspond directly to the settings you would
make in Step 2 of the Convert Text to Columns Wizard, if you were manually using the feature.
You can set Tab, Semicolon, Comma, and Space to either True or False, depending on whether you
want that character used as a delimiter.

You can also set the Other variable to True or False, depending on whether you want to have a
"user defined" delimiter. If you set it to True, then you should set the OtherChar variable equal to
the character you want used as a delimiter.

If you use the TextToColumns method multiple times in the same macro, the only thing you need to
do on invocations subsequent to the first is to change variables that differ from the previous
invocation. For instance, let's say that you are calling the method twice in the same macro, and the
first time you want the split to be on an instance of the dash character, but the second you want it to
be on any instance of a lowercase x. You can put the macro together like this:

Sub ExampleSplit2()
Dim objRange1 As Range
Dim objRange2 As Range

'Set up the ranges


Set objRange1 = Range("A2:A20")
Set objRange2 = Range("A21:A35")

'Do the first parse


objRange1.TextToColumns _
Destination:=Range("A2"), _
DataType:=xlDelimited, _
Tab:=False, _
Semicolon:=False, _
Comma:=False, _
Space:=False, _
Other:=True, _
OtherChar:="-"

'Do the second parse


objRange2.TextToColumns _
Destination:=Range("A21"), _
DataType:=xlDelimited, _
OtherChar:="x"
End Sub

Sizing Text Boxes and Cells the Same


You already know that Excel allows you to create text boxes within your worksheets. You may
have a need, at some point, to create a text box that is exactly the same size as a particular cell. If
you only have one or two such text boxes to create, the easiest way is to follow these steps if you
are using Excel 2007:
1. Display the Insert tab of the ribbon.
2. Click on the Text Box tool.
3. Hold down the Alt key as you click and drag to create your text box.

If you are using an older version of Excel, follow these steps:

1. Display the Drawing toolbar.


2. Click on the Text Box tool.
3. Hold down the Alt key as you click and drag to create your text box.

When you hold down the Alt key, it forces Excel to "snap" the sides of your text box to a drawing
grid which just happens to match the cell boundaries in your worksheet. The result is a text box that
is exactly the desired size.

If you need to create quite a few of these text boxes, all at one time, you can turn the snap-to-gird
feature on permanently. In Excel 2007 display the Page Layout tab of the ribbon, click the Align
tool in the Arrange group, then click Snap To Grid. In older versions of Excel choose Draw (on the
Drawing toolbar) | Snap | To Grid.

If you have many, many such text boxes to create, on lots of different workbooks, you can create
the desired text boxes using a macro. The following macro will create a text box directly over the
selected cell, and size it to be exactly the same size as the selected cell:

Sub TextBox2Cell()
With ActiveCell
ActiveSheet.Shapes.AddTextbox _
msoTextOrientationHorizontal, .Left, _
.Top, .Width, .Height
End With
End Sub

With a small change in the macro, you can modify it so that it will create text boxes that are just as
large as whatever range of cells you have selected:

Sub TextBox2Selection()
If TypeName(Selection) = "Range" Then
With Selection
ActiveSheet.Shapes.AddTextbox _
msoTextOrientationHorizontal, .Left, _
.Top, .Width, .Height
End With
End If
End Sub

Regardless of which approach you use to create the text box (manual or macro), it should be noted
that if you resize the cell by changing the column width or row height, the size of the text box will
also change to match the new cell size.

FUNZIONE: Eliminare caratteri iniziali fino a stringa predefinita


There are any number of ways that a user-defined function could pull the leading characters from
the words of a string. In fact, I received quite a few variations that accomplish the same thing. The
following example, however, is perhaps the most concise code that I ran across:

Function Initials(Raw As String) As String


Dim Temp As Variant
Dim J As Integer

Application.Volatile
Temp = Split(Trim(Raw))

For J = 0 To UBound(Temp)
Initials = Initials & Left(Temp(J), 1)
Next J
End Function

The Split function "tears apart" a string based on where spaces occur within it. The individual
words in the string are placed into an array (in this case, Temp) where you can then access
individual words. To use the function in your worksheet, simply use something like this:

=Initials(A1)
WORKSHEETS
Referencing a Worksheet Name in cells and in VBA
Excel provides ways to reference the column or row number of a cell, but it doesn't provide a built-
in way to reference a worksheet name. There are a couple of ways to approach this problem,
depending on what you need to do. If you are working with a worksheet that has already been
saved, then the following formula will provide you with the worksheet name for Sheet4:

=MID(CELL("filename",Sheet4!A1),FIND("]",CELL("filename",Sheet4!A1))
+1,LEN(CELL("filename", Sheet4!A1)))

You should note that there are couple of assumptions in this formula. First (and most importantly) it
assumes that you know the initial name of the worksheet. In this case, the initial name is Sheet4.
After the formula is in place, subsequent changes to the worksheet name will be reflected
automatically in the formula. The second assumption is that the workbook you are working in has
been saved. If it hasn't, then the formula returns an error until the workbook is saved and
recalculated.

A different approach is to use a user-defined function. In VBA's object model, all the worksheets in
a workbook are contained within the Sheets collection. These are, in turn, indexed. Thus, you can
pass an index value to the function and get back the name of the worksheet at the collection's index
number.

Function TabName(snum As Long) As String


Application.Volatile
If snum > 0 And snum <= Sheets.Count Then
TabName = Sheets(snum).Name
End If
End Function

For instance, if you wanted to know the name of the fourth worksheet in the collection, you could
use the following in your worksheet:

=TabName(4)

The function will work just fine, even in a workbook that has not been saved. It also returns the
proper worksheet name even if the worksheets are renamed or moved around.

Verifica l’esistenza di un foglio col nome dato


Sub CheckSheet
Dim controllo As VbMsgBoxResult
foglio=”nome foglio”
n = Sheets.Count
cancella = 0
controllo = 0

For i = 1 To n
If Sheets(i).Name = foglio Then
cancella = i
controllo = MsgBox("Il foglio di questo mese è già presente
nell'archivio! Vuoi sovrascriverlo?", _
vbYesNo, "ATTENZIONE!")
End If
Next

If controllo <> 0 Then


If controllo = vbNo Then
ActiveWindow.Close
Exit Sub
Else
Application.DisplayAlerts = False
Sheets(cancella).Delete
Application.DisplayAlerts = True
End If
End If
End Sub

Rinomina fogli all’interno di un array di file


Sub RinominaFogli()

MyPath = "C:\Documents and Settings\user\"


oldname = "nomevecchio"
newname = "nomenuovo"

file = Dir(MyPath, vbNormal)

Application.DisplayAlerts = False

Do While file <> ""


Workbooks.Open Filename:=MyPath & file
Sheets(oldname).Name = newname
ActiveWorkbook.Close (True)
file = Dir
Loop

Application.DisplayAlerts = True

End Sub

Protezione e sprotezione di ogni foglio della cartella


Sub For_Each()
Dim mysheet As Worksheet
' dimensiona la variabile come un foglio
Set mysheet = Worksheets(1)
' assegna per ora il valore di mySheet uguale al foglio 1
mysheet.Protect "puffo"
‘protegge SOLO il foglio 1 con la pw “puffo”

For Each mySheets In Worksheets


' ora crea un ciclo per tutti i fogli
    mySheets.Protect "puffo"
Next mySheets
End Sub

Un foglio molto nascosto


Esiste una modalità che impedisce al menu Scopri di visualizzare uno o più fogli nascosti,
accessibile solo dal VBA; via interfaccia grafica si può accedere al riquadro Proprietà e, nell'ultimo
campo, chiamato Visible, la proprietà “molto nascosto” (opzione 1-xlSheetVeryHidden).
Da codice, presumibilmente, sarà:
Sheets(“Foglio1”).xlSheetVisibility.xlSheetVeryHidden (da testare)

Se il foglio è "very hidden" l'unico modo per poterlo nuovamente visualizzare è accedere al menu
Proprietà dell'editor Visual Basic e ripristinare l'opzione -1SheetVisible

Combining Worksheets from Many Workbooks


The following macro, CombineSheets, is interactive in nature. It asks you for several pieces of
information, and then adds worksheets to the workbook based upon your responses. It first asks for
a path to the worksheets (don't include the trailing slash) and then for a pattern to use for the
workbooks. You can specify a workbook pattern using the regular asterisk (*) and question mark (?)
wildcards. For instance, a pattern of * would match all workbooks, while a pattern of Budget20??
would return only workbooks that have "Budget20" at the beginning and any two characters after
that.

Sub CombineSheets()
Dim sPath As String
Dim sFname As String
Dim wBk As Workbook
Dim wSht As Variant

Application.EnableEvents = False
Application.ScreenUpdating = False
sPath = InputBox("Enter a full path to workbooks")
ChDir sPath
sFname = InputBox("Enter a filename pattern")
sFname = Dir(sPath & "\" & sFname & ".xl*", vbNormal)
wSht = InputBox("Enter a worksheet name to copy")
Do Until sFname = ""
Set wBk = Workbooks.Open(sFname)
Windows(sFname).Activate
Sheets(wSht).Copy Before:=ThisWorkbook.Sheets(1)
wBk.Close False
sFname = Dir()
Loop
ActiveWorkbook.Save
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub

When you run the macro you are also asked for the name of a worksheet to copy from each
matching workbook. Provide a name, and if such a worksheet exists in the workbook it is copied to
the beginning of the current workbook.

If you prefer not to create your own macro for combining worksheets, you might consider the
RDBMerge add-in created by Excel MVP Ron de Bruin. You can find it for free, here:

http://www.rondebruin.nl/merge.htm

Running a Macro When a Worksheet is Deactivated


It is possible to configure Excel so that a macro of your choosing is executed every time a particular
worksheet is deactivated. What does that mean? Simply that a macro can be run every time you
click on a worksheet tab to leave the current sheet. All you need to do is follow these steps:
1. Activate the worksheet with which you want the macro associated.
2. Choose Name from the Insert menu. You will see a submenu.
3. Choose Define from the submenu. You will see the Define Name dialog box. In the Names
in Workbook field, enter a name that begins with the worksheet name, followed by an
exclamation point, Auto_Deactivate, and any other wording desired. Thus, if the worksheet
were named Stocks, you might enter Stocks!Auto_Deactivate_Exit.
4. In the Refers to field, enter a formula that points to the workbook and macro you want
automatically executed. Thus, if the macro name were Update_PL, and the workbook name
were PFOLIO.XLS, you would enter the formula =PFolio!Update_PL.
5. Click on the OK button.

If you are using Excel 2007, then you define the requisite macro names in this manner:

1. Activate the worksheet with which you want the macro associated.
2. Make sure the Formulas tab of the ribbon is displayed.
3. In the Defined Names area of the ribbon, click Define Name. Excel displays the New Name
dialog box. In the Name field, enter a name that begins with the worksheet name, followed
by an exclamation point, Auto_Deactivate, and any other wording desired. Thus, if the
worksheet were named Stocks, you might enter Stocks!Auto_Deactivate_Exit.
4. In the Refers to box, enter a formula that points to the workbook and macro you want
automatically executed. Thus, if the macro name were Update_PL, and the workbook name
were PFOLIO.XLS, you would enter the formula =PFolio!Update_PL.
5. Click on the OK button.

Remember that a macro defined in this way is run every time the worksheet is deactivated, not just
the first time. Think about how you use Excel; if you spend a fair amount of time hopping between
worksheets in a workbook or between workbooks, it is possible to deactivate a worksheet several
dozen times during the course of a session.

Sorting Data on Protected Worksheets


When you protect a worksheet, Excel stops users from performing a wide variety of tasks on the
data in the worksheet. One of the things that the user can no longer do is to sort data. What if you
want the user to be able to sort data, but still have the sheet protected?

If you are using Excel 2002, Excel 2003, or Excel 2007 the answer is quite easy: These versions of
Excel allow you to specify what users can and cannot do with a protected worksheet. When you
choose Tools | Protection | Protect Sheet (Excel 2002 and Excel 2003) or display the Review tab of
the ruler and click Protect Sheet in the Changes group (Excel 2007), Excel displays the Protect
Sheet dialog box. At the bottom of the dialog box is a long list of check boxes. All you need to do is
select what the user should be able to do with the worksheet. One of the options (you need to scroll
down a bit) is Sort. If you select this option, then users can sort protected data.

If you are using an older version of Excel, the solution is to create a macro that unprotects the
worksheet, sorts the data, and then protects the worksheet again. The following is a simple example:

Sub Sorting()
ActiveSheet.Unprotect
Range("A1:D100").Sort Key1:=Range("A1"), _
Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom
ActiveSheet.Protect
End Sub

This example sorts the data in the range A1:D100 based on the contents of column A. The macro
illustrates the general concept behind this approach, but you will need to modify it to reflect the
needs of your data and your users.

If you go the macro route, you need to assign the macro to either a toolbar button or a menu
command. If you don't the user will never be able to use it, since the Macros menus are disabled in
a protected document.

Crack Sheet Protection Password


This routine provides a password to unprotect your worksheet. However, it may not give you the
original password that was used.
Open the workbook that has the protected sheet in it. Hit Alt+F11 to view the Visual Basic Editor.
Hit Insert-Module and paste this code into the right-hand code window:

Sub PasswordBreaker()  
  Dim i As Integer, j As Integer, k As Integer
  Dim l As Integer, m As Integer, n As Integer
  Dim i1 As Integer, i2 As Integer, i3 As Integer
  Dim i4 As Integer, i5 As Integer, i6 As Integer

  On Error Resume Next

  For i = 65 To 66: For j = 65 To 66: For k = 65 To 66


  For l = 65 To 66: For m = 65 To 66: For i1 = 65 To 66
  For i2 = 65 To 66: For i3 = 65 To 66: For i4 = 65 To 66
  For i5 = 65 To 66: For i6 = 65 To 66: For n = 32 To 126
     
        
 ActiveSheet.Unprotect Chr(i) & Chr(j) & Chr(k) & _
      Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & Chr(i3) & _
      Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
  If ActiveSheet.ProtectContents = False Then
      MsgBox "One usable password is " & Chr(i) & Chr(j) & _
          Chr(k) & Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & _
          Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
   ActiveWorkbook.Sheets(1).Select
   Range("a1").FormulaR1C1 = Chr(i) & Chr(j) & _
          Chr(k) & Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & _
          Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
       Exit Sub
  End If
  Next: Next: Next: Next: Next: Next
  Next: Next: Next: Next: Next: Next

End Sub

Close the VB Editor window. Navigate to the worksheet you want to unprotect. Hit Tools-Macro-
Macros and double-click PasswordBreaker in the list.
Locking Worksheet Names
If you are developing workbooks for others to use, you may want your worksheets to retain
whatever names you give them. Excel normally allows users to change worksheet names, as
desired. If you don't want them to change, the only way to prevent it is to lock the workbook. You
can take these steps if you are using a version of Excel prior to Excel 2007:
1. Display the Protect Workbook dialog box. Do this by choosing Tools | Protection | Protect
Workbook. (In Excel 2007 display the Protect Structure and Windows dialog box by
displaying the Review tab of the ribbon and clicking Protect Workbook in the Changes
group.)
2. Make sure that the Structure check box is selected.
3. Enter a password in the Password box.
4. Click on OK. Excel displays the Confirm Password dialog box, prompting you to reenter the
password.
5. Reenter the password and click on OK.

The user can no longer make changes to the names of the worksheet tabs, nor to anything else that
affects the structure of the workbook. (For instance, they cannot enter new worksheets or delete
existing ones.)

If you want to protect the workbook under the control of a macro, then you can use this code:

ActiveWorkbook.Protect Password:="MyPassword", Structure:=True

All you need to do is provide password you want to use in place of the "MyPassword" example.

Running Macros on Hidden Worksheets


Macros are often used to process information within a workbook. Your macro can access any cells
in the workbook, unless the worksheet containing the cell is hidden. When you hide a worksheet, it
is even hidden from normal macro operations. The upshot of this is that if you want to run a macro
and have it access information on a hidden worksheet, you must first "unhide" the worksheet. To do
this, you use the following line of code in your macro:

Sheets("My Hidden Sheet").Visible = True

When this line is executed, then the worksheet named My Hidden Sheet will no longer be hidden. It
is then easily accessible by regular macro commands. When you are later ready to hide the
worksheet again (when you are done processing), use this line of code:

Sheets("My Hidden Sheet").Visible = False

Of course, unhiding and later hiding worksheets can cause a lot of flashing on the screen as Excel
tries to update its screen display based on the commands executed in your macro. If you want to
avoid this, then use the following line of code at the beginning of your macro:

Application.ScreenUpdating = False

With screen updating turned off in this way, nobody will ever know that you unhid a worksheet and
later rehid it.
Creating Worksheets with a Macro
The following code will add the worksheet, but keep asking for a worksheet name if an
incorrect one (by Excel standards) is supplied.

Sub AddNameNewSheet2()
Dim CurrentSheetName As String

'Remember where we started


'Not needed if you don't want to return
'to where you started but want to stay
'on the New Sheet

CurrentSheetName = ActiveSheet.Name

'Add New Sheet


Sheets.Add

'Make sure the name is valid


On Error Resume Next

'Get the new name


ActiveSheet.Name = InputBox("Name for new worksheet?")

'Keep asking for name if name is invalid


Do Until Err.Number = 0
Err.Clear
ActiveSheet.Name = InputBox("Try Again!" _
& vbCrLf & "Invalid Name or Name Already Exists" _
& vbCrLf & "Please name the New Sheet")
Loop
On Error GoTo 0

'Go back to where you started


'Not needed if you don't want to return
'to where you started but want to stay
'on the New Sheet
Sheets(CurrentSheetName).Select

End Sub

Condensing Multiple Worksheets Into One


If you get workbooks that have identically structured data on each worksheet, you may be interested
in a way to combine the multiple worksheets into a single, large worksheet.
The concept behind doing the condensation is rather easy: You simply need to copy the data from
the second and subsequent worksheets to the first empty row on the first worksheet. Fortunately,
Excel includes a feature that allows you to do this very process—the Consolidate tool.
The Consolidate tool allows you to combine worksheets where data is defined by position or by
category. By position means that the data is in the same position on every worksheet. For instance,
if the data tables on each worksheet have the exact same columns, then you would consolidate by
position. By category means that you want to combine data from tables in which the data may not
use a consistent structure. You use this type of consolidation if the columns in the data tables are in
different orders.
In the workbook whose worksheets you want to consolidate, choose Data | Consolidate. Excel
displays the Consolidate dialog box. (Click here to see a related figure.) There are many controls in
the dialog box, but the primary thing you need to worry about is specifying the ranges to
consolidate.
You specify ranges by using the Reference box. Specify in the box the first range you want to
consolidate. If you are consolidating by position, then the reference should not contain any column
labels; if by category, then you should. When you specify the range reference, you click Add, and
the reference appears in the All References list. You continue to define reference ranges until they
are all complete.
If you want the consolidated data to contain links to the original data, then make sure the Create
Links to Source Data check box is selected, otherwise clear it. You can then click OK to do the
consolidation.
Note that there are other controls in the Consolidate dialog box; the controls mentioned above are
the ones you should pay attention to at a minimum. The best way to find out what the others do is to
play around with them, doing a few consolidations.
If you prefer to not use the Consolidate tool, you can easily create a macro that will do the
consolidation for you—provided the structure of each worksheet is identical. The following macro
steps through all the worksheets and combines the data to a new worksheet it adds at the beginning
of the workbook.

Sub Combine()
Dim J As Integer

On Error Resume Next


Sheets(1).Select
Worksheets.Add ' add a sheet in first place
Sheets(1).Name = "Combined"

' copy headings


Sheets(2).Activate
Range("A1").EntireRow.Select
Selection.Copy Destination:=Sheets(1).Range("A1")

' work through sheets


For J = 2 To Sheets.Count ' from sheet 2 to last sheet
Sheets(J).Activate ' make the sheet active
Range("A1").Select
Selection.CurrentRegion.Select ' select all cells in this sheets

' select all lines except title


Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select

' copy cells selected in the new sheet on last line


Selection.Copy Destination:=Sheets(1).Range("A65536").End(xlUp)(2)
Next
End Sub

When the macro is done, the first sheet in the workbook, named Combined, has all the data from the
other worksheets. The other worksheets remain unchanged.
GESTIONE ERRORI
Gestione degli errori
Sub GestioneErrore()

'primo metodo
On Error Resume Next
Worksheets(1000).Activate
MsgBox "Errore saltato"

'secondo metodo
Worksheets(1000).Activate
On Error GoTo oltreErrore
Worksheets(15).Activate
oltreErrore:
MsgBox "Errore saltato anche in questo caso"
End Sub

Finding and Replacing Error Values


You have a huge worksheets with hundreds of rows of calculated values. Inevitably there will be
scattered cells with the #N/A error that you would like to all be 0 (or some other value) so you can
use the cells in other formulas. Due to the calculations you are running, an IF formula or other such
method to anticipate and remove these values from the calculation is usually impossible, and it's
very tedious to remove them by hand. There are a couple of ways you can approach this issue. One
is to use the Go To feature in Excel. Simply follow these steps:
1. Press F5. Excel displays the Go To dialog box.
2. Click Special. Excel displays the Go To Special dialog box.
3. Make sure the Formulas radio button is selected.
4. The only check box that should be selected under Formulas is Errors.
5. Click OK. Excel selects all cells where the formula returned an error value.
6. Type 0 or whatever value you want.
7. Press Ctrl+Enter.

Note that this approach results in any error values being replaced, not just those with the #N/A
error. If you have to make the replacements quite a bit or you want to only affect #N/A errors, you
may want to use a macro to do the replacements:

Sub Replace_NAs()
Dim C
For Each C In ActiveSheet.UsedRange
If Application.WorksheetFunction.IsNA(C) Then
C.Value = 0
End If
Next
End Sub

You should note that all these options result in the formulas in the cells (those that returned the
#N/A values) being permanently replace with a 0 or whatever value you specify. The only way to
not replace the formulas is to change those formulas to use an IF statement to check for the error
condition before applying the formula.
VARIABILI
Use VbNullString to get a String variable back to its default value
Sub EmptyText()
Dim strWords As String

strWords = "Cats"
MsgBox strWords
strWords = vbNullString
MsgBox strWords
End Sub

To quickly view a variables definition:


Select the variable that you want the definition for.
Go to View>Definition (Shift+F2)

To return to your previous position:


Go to View>Last Position (Ctrl+Shift+F2).

Release memory from Object variables:


Sub ReleaseObjectMemory()
'Could be any variable of the Object type

Dim wSheet as Worksheet

'Set Object variable

Set wSheet = Sheet1

'Your code here.


'Release memory

Set wSheet = Nothing


End Sub

Quickly Dumping Array Contents


If you have done any programming in VBA, you know the value of using variable arrays to store
information. It is not uncommon to start working with large arrays in your macros. For instance,
you might declare a 100-element string array, as follows:

Dim MyText(99) As String

As your macro executes, information can be stored and restored in the elements of the array. At
some time, you may want to erase all the information in the array. One classic way of doing this is
using a For ... Next loop to step through each array element, as follows:

For J = 0 To 99
MyText(J) = ""
Next J

When the looping is complete, everything has been erased from the array. A quicker way of
accomplishing the same task is to use the ERASE function, as follows:
Erase MyText
Once executed, this single line sets each element of the MyText array back to an empty string. If the
array is numeric, then each element of the array is set to zero.
INTEGRAZIONE OFFICE
Getting Excel Dates into Outlook's Calendar
Working with Outlook is a bit "higher level" than your run-of-the-mill Excel macro because you
need to understand not only how to access Excel data in the macro, but also how to manipulate
Outlook data. Without knowing exactly what data you need to transfer from the worksheet to the
Outlook appointment, let's examine a short scenario.

Let's assume that you have a worksheet that contains a series of rows, each of which represents a
single appointment you want to create. Each appointment contains information in seven columns, as
follows, from left to right:

 Subject. Text that describes the event/appointment (for example, "Yellow Pages
Reminder")
 Location. Text that describes the location of the event, such as a meeting room or a
conference call number (this is optional)
 Start Date/Time. Enter the date and time the event should start using a standard Excel date
format (you can display any way you like)
 Duration. Integer that represents a number of minutes for the appointment
 Busy Status. Integer that represents an optional value indicating if the time should show as
Free (0), Tentative (1), Busy (2), or Out of Office (3)
 Reminder Time. Integer that represents a number of minutes before the appointment that a
reminder should pop-up (as in 4320 which is the number of minutes in 3 days)
 Body. Text that describes any detail you might want to place in the body of the appointment

With this data in place, you can use a macro to loop through all the rows (starting with the second
row, assuming the first row has headings) and create an appointment for each row.

Sub AddAppointments()
' Create the Outlook session
Set myOutlook = CreateObject("Outlook.Application")

' Start at row 2


r = 2

Do Until Trim(Cells(r, 1).Value) = ""


' Create the AppointmentItem
Set myApt = myOutlook.createitem(1)
' Set the appointment properties
myApt.Subject = Cells(r, 1).Value
myApt.Location = Cells(r, 2).Value
myApt.Start = Cells(r, 3).Value
myApt.Duration = Cells(r, 4).Value
' If Busy Status is not specified, default to 2 (Busy)
If Trim(Cells(r, 5).Value) = "" Then
myApt.BusyStatus = 2
Else
myApt.BusyStatus = Cells(r, 5).Value
End If
If Cells(r, 6).Value > 0 Then
myApt.ReminderSet = True
myApt.ReminderMinutesBeforeStart = Cells(r, 6).Value
Else
myApt.ReminderSet = False
End If
myApt.Body = Cells(r, 7).Value
myApt.Save
r = r + 1
Loop
End Sub

The macro continues to loop through the rows until the Subject column is empty.

Dynamic Hyperlinks in Excel


You can create dynamic hyperlinks in Excel that act like HTML forms without having to know
much at all about HTML. These hyperlinks can come in handy when using Excel as an interface to
the Internet or to an internal Web.

As an example, let's create a Google search form. First, drop by Google.com and do a search for the
keyword "Excel." Then, take a look at the URL in your browser's address bar. It may look
something like this:

http://www.google.com/search?hl=en&q=Excel&lr=lang_en

The parameters following the question mark (?) are the name-value pairs submitted by the HTML
form. But, you don't need to know a whole lot about that. In this case, the main thing to consider is
the search term, where "q" is the name of the parameter, and "Excel" is the value.

Using the HYPERLINK function along with the CONCATENATE function (or just the ampersand,
&), you can easily assemble a link and create a dynamic form using cells as fields. Just follow these
two quick steps:

1. In cell B3 enter the keyword "Excel Web Queries."


2. In cell B4, enter the following formula:

=HYPERLINK("http://www.google.com/search?q="&B3&"&safe=active","Search
Google")

Now you have your own simple HTML form inside of Excel. You can create much longer
hyperlinks and include multiple cell references, but there is a limit in Excel to how long the
hyperlink can be (about 248 characters). To use the form, just enter your keywords into cell
B3, and click on the hyperlink in cell B4. That's it!

Creating a form to access Google is just a simplistic example. The interesting applications
are when you can assemble hyperlinks from the results of calculations, string manipulation,
IF statements, combo boxes, or the other form fields available in Excel.

Creazione batch di email in Outlook


La routine che segue estrae alcune righe da un foglio Excel, le converte in formato HTML e le
passa ad Outlook; alternativamente, se è su

Sub InviaWiP()
' requires a reference to the Microsoft Outlook 8.0 Object Library
' creates and sends a new e-mail message with Outlook
Dim OLF As Outlook.MAPIFolder, olMailItem As Outlook.MailItem
Dim ToContact As Outlook.Recipient
Dim indirizzi As String, gruppo As String, gr(5) As String
Dim copia As Range
Dim strBody As String
Dim nomemese(12) As String, nomemeseup(12) As String

Set OLF =
GetObject("","Outlook.Application").GetNamespace("MAPI").GetDefaultFolder
_(olFolderInbox)
Set olMailItem = OLF.Items.Add ' creates a new e-mail message

'Estrai le Righe da inviare

Set copia = Range("A4", ActiveCell.Offset(0,18)).SpecialCells(xlCellTypeVisible)


copia.Copy

With olMailItem
.Subject = "Soggetto della mail” ‘add the subject
Set ToContact = .Recipients.Add(indirizzo) 'add a recipient

'qui inserire il corpo mex con un line break


'.Body = "In allegato il bollettino “ & Chr(13)

'qui inserire il corpo mex con l'estratto di excel


strBody = "In allegato il bollettino & "<br>"
' l'a capo è <br> perchè è html!

.HTMLBody = strBody

.HTMLBody = strBody & RangetoHTML(copia)

allegato = path & nomefile


.Attachments.Add allegato, olByValue, , "Attachment"
' insert attachment

.OriginatorDeliveryReportRequested = False
' delivery confirmation
.ReadReceiptRequested = False
' read confirmation
.Save
' saves the message in Drafts for later editing
'.Send
' sends the e-mail message (puts it in the Outbox)
End With
Set ToContact = Nothing
Set olMailItem = Nothing
Set OLF = Nothing

' .Attachments.Add "C:\FolderName\Filename.txt", olByReference, , _


"Shortcut to Attachment" ' insert shortcut
' .Attachments.Add "C:\FolderName\Filename.txt", olEmbeddedItem, , _
"Embedded Attachment" ' embedded attachment
' .Attachments.Add "C:\FolderName\Filename.txt", olOLE, , _
"OLE Attachment" ' OLE attachment

End Sub
Conversione di un range in formato HTML (Funzione)
Questa funzione prende in input il range denominato “copia” e lo converte in formato HTML per
l’invio tramite Outlook

Function RangetoHTML(copia As Range)


' Changed by Ron de Bruin 28-Oct-2006
' Working in Office 2000-2010
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook

TempFile = Environ$("temp") & "/" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"

'Copy the range and create a new workbook to past the data in
copia.Copy
Set TempWB = Workbooks.Add(1)
With TempWB.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
End With

'Publish the sheet to a htm file


With TempWB.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=TempFile, _
Sheet:=TempWB.Sheets(1).Name, _
Source:=TempWB.Sheets(1).UsedRange.Address, _
HtmlType:=xlHtmlStatic)
.Publish (True)
End With

'Read all data from the htm file into RangetoHTML


Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
RangetoHTML = ts.ReadAll
ts.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")

'Close TempWB
TempWB.Close savechanges:=False

'Delete the htm file we used in this function


Kill TempFile

Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function
Invio dei messaggi contenuti nella cartella “Bozze” di Outlook
Public Sub SendDrafts()

Dim lDraftItem As Long


Dim myOutlook As Outlook.Application
Dim myNameSpace As Outlook.Namespace
Dim myFolders As Outlook.Folders
Dim myDraftsFolder As Outlook.MAPIFolder

'Send all items in the "Drafts" folder that have a "To" address filled in.

'Setup Outlook

Set myOutlook = Outlook.Application


Set myNameSpace = myOutlook.GetNamespace("MAPI")
Set myFolders = myNameSpace.Folders

'Set Draft Folder. This will need modification based on where it's being run.

Set myDraftsFolder = myFolders("Cassetta postale - valmori").Folders("Bozze")

'Loop through all Draft Items

For lDraftItem = myDraftsFolder.Items.Count To 1 Step -1

'Check for "To" address and only send if "To" is filled in.

If Len(Trim(myDraftsFolder.Items.Item(lDraftItem).To)) > 0 Then

'Send Item

myDraftsFolder.Items.Item(lDraftItem).Send

End If
Next lDraftItem

'Clean-up

Set myDraftsFolder = Nothing


Set myNameSpace = Nothing
Set myOutlook = Nothing

controllo = MsgBox("Invio completato!", vbYes, "ATTENZIONE!")

End Sub

Nascondere l’apertura di Excel da parte di applicazione esterna


Application.Visible=False
Aggiungere alle date la notazione ordinale inglese
When developing a workbook, you may have a need to place suffixes such as "st, nd, rd, or th" at
the end of dates, as in "9th July." Unfortunately, there is no way to do this using the built-in date
formats you can apply to individual cells. You can create custom formats for each of the four suffix
types, if desired, but they would have to be applied individually based on the contents of the cell
itself.
The only other option is to use some sort of conversion formula. These are easy enough to put
together, but the resulting cell will not contain a true Excel date, but text. This precludes the cell
contents from being used in other date-related functions. The following is an example of the type of
conversion formula you can use:

=DAY(A1)&IF(OR(DAY(A1)={1,2,3,21,22,23,31}),
CHOOSE(1*RIGHT(DAY(A1),1),"st","nd ","rd "),"th")
&TEXT(A1,"mmmm, yyyy")

There are others, but they all essentially do the same thing—pull the various parts of a date apart
and put them back together with the proper suffix.
If you prefer, you can also create a macro function that would return a properly formatted date, with
the ordinal suffix. The following is one such macro:

Function OrdinalDate(myDate As Date)


Dim dDate As Integer
Dim dText As String
Dim mDate As Integer
Dim mmmText As String

dDate = Day(myDate)
mDate = Month(myDate)

Select Case dDate


Case 1: dText = "st"
Case 2: dText = "nd"
Case 3: dText = "rd"
Case 21: dText = "st"
Case 22: dText = "nd"
Case 23: dText = "rd"
Case 31: dText = "st"
Case Else: dText = "th"
End Select

Select Case mDate


Case 1: mmmText = " January"
Case 2: mmmText = " February"
Case 3: mmmText = " March"
Case 4: mmmText = " April"
Case 5: mmmText = " May"
Case 6: mmmText = " June"
Case 7: mmmText = " July"
Case 8: mmmText = " August"
Case 9: mmmText = " September"
Case 10: mmmText = " October"
Case 11: mmmText = " November"
Case 12: mmmText = " December"
End Select

OrdinalDate = dDate & dText & mmmText


End Function
You use the macro by simply invoking it within a cell formula. For example, if you have a date
stored in cell B7, you can use the following in any other cell:

=OrdinalDate(B7)
GENERALITA’
Metodi e Proprietà nel VBA di EXCEL

Nella sintassi di VBA esistono 2 tipi di membro:

PROPRIETA’: membro che indica una caratteristica di un oggetto come , per esempio,
NumberFormat. Le proprietà sono seguite da =

METODO: membro che indica un'operazione da fare su un oggetto, come per esempio Copy
e PasteSpecial. I metodi possono non essere seguiti da niente (come per esempio Copy)
oppure essere seguiti da argomenti che specificano la modalità in cui il metodo deve essere
eseguito (per esempio PasteSpecial).. Tali argomenti sono preceduti da :=

Variabili

Sostanzialmente esistono due tipi di variabili: quella uguale al valore contenuto in una cella
e quella uguale ad un determinato oggetto; la prima si scrive

MyVar = Range("c5")

e assegna alla variabile il valore contenuto all'interno della cella.

La seconda si scrive

Set MyVar = Range("c3").Interior

e consente di chiamare una determinata proprietà col nome della variabile: la differenza sta
nel fatto che si scrive Set all'inizio
CORRISPONDENZA FUNZIONI
ITALIANO - INGLESE
Italian English
ADESSO NOW
AMBIENTE.INFO INFO
AMMORT DDB
AMMORT.ANNUO SYD
AMMORT.COST SLN
AMMORT.FISSO DB
AMMORT.VAR VDB
ANNO YEAR
ANNULLA.SPAZI TRIM
APPLICAZ.TITOLO APP.TITLE
APRI.DIALOGO OPEN.DIALOG
ARCCOS ACOS
ARCCOSH ACOSH
ARCSEN ASIN
ARCSENH ASINH
ARCTAN ATAN
ARCTAN.2 ATAN2
ARCTANH ATANH
AREE AREAS
ARGOMENTO ARGUMENT
ARROTONDA ROUND
ARROTONDA.DIFETTO FLOOR
ARROTONDA.ECCESSO CEILING
ARROTONDA.PER.DIF ROUNDDOWN
ARROTONDA.PER.ECC ROUNDUP
ASC ASC
ASIMMETRIA SKEW
ASS ABS
ATTIVA.STRUMENTO ENABLE.TOOL
BARRA.AGGIUNGI ADD.BAR
BARRA.DEGLI.STRUMENTI.AGGIUNGI ADD.TOOLBAR
BARRA.DEGLI.STRUMENTI.ELIMINA DELETE.TOOLBAR
BARRA.ELIMINA DELETE.BAR
BARRA.MOSTRA SHOW.BAR
CASELLA.DI.TESTO TEXT.BOX
CASUALE RAND
CELLA CELL
CELLA.VALORE SET.VALUE
CERCA LOOKUP
CERCA.B SEARCHB
CERCA.ORIZZ HLOOKUP
CERCA.VERT VLOOKUP
CODICE CODE
CODICE.CARATT CHAR
COLONNE COLUMNS
COMANDO.AGGIUNGI ADD.COMMAND
COMANDO.ANIMAZIONE MOVIE.COMMAND
COMANDO.ATTIVA ENABLE.COMMAND
COMANDO.ELIMINA DELETE.COMMAND
COMANDO.RINOMINA RENAME.COMMAND
COMANDO.SEGNA CHECK.COMMAND
COMBINAZIONE COMBIN
CONCATENA CONCATENATE
CONFIDENZA CONFIDENCE
CONFRONTA MATCH
CONTA.NUMERI COUNT
CONTA.PIU.SE COUNTIFS
CONTA.SE COUNTIF
CONTA.VALORI COUNTA
CONTA.VUOTE COUNTBLANK
CONTROLLA.ORTOGRAFIA SPELLING.CHECK
CORRELAZIONE CORREL
COS COS
COSH COSH
COVARIANZA COVAR
CRESCITA GROWTH
CRIT.BINOM CRITBINOM
CURTOSI KURT
DATA DATE
DATA.VALORE DATEVALUE
DATEDIF DATEDIF
DATESTRING DATESTRING
DATI.INVIA POKE
DB.CONTA.NUMERI DCOUNT
DB.CONTA.VALORI DCOUNTA
DB.DEV.ST DSTDEV
DB.DEV.ST.POP DSTDEVP
DB.MAX DMAX
DB.MEDIA DAVERAGE
DB.MIN DMIN
DB.PRODOTTO DPRODUCT
DB.SOMMA DSUM
DB.VALORI DGET
DB.VAR DVAR
DB.VAR.POP DVARP
DBCS DBCS
DDE.APRI INITIATE
DDE.CHIUDI TERMINATE
DESTRA RIGHT
DESTRA.B RIGHTB
DEV.Q DEVSQ
DEV.ST STDEV
DEV.ST.POP STDEVP
DIRECTORY DIRECTORY
DISPARI ODD
DISTRIB.BETA BETADIST
DISTRIB.BINOM BINOMDIST
DISTRIB.BINOM.NEG NEGBINOMDIST
DISTRIB.CHI CHIDIST
DISTRIB.EXP EXPONDIST
DISTRIB.F FDIST
DISTRIB.GAMMA GAMMADIST
DISTRIB.IPERGEOM HYPGEOMDIST
DISTRIB.LOGNORM LOGNORMDIST
DISTRIB.NORM NORMDIST
DISTRIB.NORM.ST NORMSDIST
DISTRIB.T TDIST
DOC.APERTI DOCUMENTS
DOC.NOMI NAMES
E AND
ERR.STD.YX STEYX
ERRORE ERROR
ERRORE.TIPO ERROR.TYPE
ERRORE.ULTIMO LAST.ERROR
ESEGUI.COMANDO EXECUTE
ESEGUI.PROGRAMMA EXEC
EXP EXP
FALSO FALSE
FATTORIALE FACT
FERMA HALT
FILE.APRI.NUM FOPEN
FILE.CHIUDI.NUM FCLOSE
FILE.IN.DIRECTORY FILES
FILE.LEGGI FREAD
FILE.LEGGI.RIGA FREADLN
FILE.NUM.CARATTERI FSIZE
FILE.POSIZIONA FPOS
FILE.SCRIVI FWRITE
FILE.SCRIVI.RIGA FWRITELN
FINESTRA.DI.DIALOGO DIALOG.BOX
FINESTRE WINDOWS
FISHER FISHER
FISSO FIXED
FORMATO.RAGGRUPPA GROUP
FORMULA.CONVERTI FORMULA.CONVERT
FORMULA.NOTA NOTE
FREQUENZA FREQUENCY
GIORNO DAY
GIORNO.SETTIMANA WEEKDAY
GIORNO360 DAYS360
GRADI DEGREES
GRANDE LARGE
GUIDA HELP
IDENTICO EXACT
IDENTIFICATORE.REGISTRO REGISTER.ID
INDICE INDEX
INDIRETTO INDIRECT
INDIRIZZO ADDRESS
INFO.ANIMAZIONE GET.MOVIE
INFO.AREA.DI.LAVORO GET.WORKSPACE
INFO.BARRA GET.BAR
INFO.BARRA.DEGLI.STRUMENTI GET.TOOLBAR
INFO.CAMPO.PIVOT GET.PIVOT.FIELD
INFO.CARTELLA.DI.LAVORO GET.WORKBOOK
INFO.CELLA GET.CELL
INFO.COLLEGAM GET.LINK.INFO
INFO.DEF GET.DEF
INFO.DOC GET.DOCUMENT
INFO.ELEMENTO.PIVOT GET.PIVOT.ITEM
INFO.FILE.COLLEGAM LINKS
INFO.FINESTRA GET.WINDOW
INFO.FORMULA GET.FORMULA
INFO.GRAFICO.ELEM GET.CHART.ITEM
INFO.NOME GET.NAME
INFO.NOTA GET.NOTE
INFO.OGGETTO GET.OBJECT
INFO.RICHIEDI REQUEST
INFO.STRUMENTO GET.TOOL
INFO.TABELLA.PIVOT GET.PIVOT.TABLE
INPUT INPUT
INT INT
INTERCETTA INTERCEPT
INTERESSI IPMT
INV.BETA BETAINV
INV.CHI CHIINV
INV.F FINV
INV.FISHER FISHERINV
INV.GAMMA GAMMAINV
INV.LOGNORM LOGINV
INV.NORM NORMINV
INV.NORM.ST NORMSINV
INV.T TINV
ISPMT ISPMT
LIBERA CLEAN
LN LN
LN.GAMMA GAMMALN
LOG LOG
LOG10 LOG10
LUNGB LENB
LUNGHEZZA LEN
MAIUSC UPPER
MAIUSC.INIZ PROPER
MATR.DETERM MDETERM
MATR.INVERSA MINVERSE
MATR.PRODOTTO MMULT
MATR.SOMMA.PRODOTTO SUMPRODUCT
MATR.TRASPOSTA TRANSPOSE
MAX MAX
MEDIA AVERAGE
MEDIA.ARMONICA HARMEAN
MEDIA.B MIDB
MEDIA.DEV AVEDEV
MEDIA.GEOMETRICA GEOMEAN
MEDIA.TRONCATA TRIMMEAN
MEDIANA MEDIAN
MENU.AGGIUNGI ADD.MENU
MENU.ELIMINA DELETE.MENU
MESE MONTH
MIN MIN
MINUSC LOWER
MINUTO MINUTE
MODA MODE
NOME.RIF SET.NAME
NON NOT
NON.DISP NA
NORMALIZZA STANDARDIZE
NUM N
NUM.RATE NPER
NUMBERSTRING NUMBERSTRING
O OR
OGGETTO.CREA CREATE.OBJECT
OGGI TODAY
OPZIONI.ELENCHI OPTIONS.LISTS.GET
ORA HOUR
ORARIO TIME
ORARIO.VALORE TIMEVALUE
P.RATA PPMT
PARI EVEN
PASSO STEP
PAUSA PAUSE
PEARSON PEARSON
PENDENZA SLOPE
PERCENT.RANGO PERCENTRANK
PERCENTILE PERCENTILE
PERMUTAZIONE PERMUT
PERSONAL.ANNULLA CUSTOM.UNDO
PERSONAL.RIPETI CUSTOM.REPEAT
PI.GRECO PI
PICCOLO SMALL
PIVOT.AGGIUNGI.DATI PIVOT.ADD.DATA
POISSON POISSON
POTENZA POWER
PREMI.STRUMENTO PRESS.TOOL
PREVISIONE FORECAST
PROBABILITÀ PROB
PRODOTTO PRODUCT
QUARTILE QUARTILE
RADIANTI RADIANS
RADQ SQRT
RANGO RANK
RATA PMT
REGISTRO REGISTER
REGISTRO.ELIMINA UNREGISTER
REGR.LIN LINEST
REGR.LOG LOGEST
RESTO MOD
RIAVVIA RESTART
RICERCA SEARCH
RICHIAMA CALL
RIF.ASS ABSREF
RIF.CELLA.ATTIVA ACTIVE.CELL
RIF.COLONNA COLUMN
RIF.REL RELREF
RIF.RICHIAMO CALLER
RIF.RIGA ROW
RIF.SELEZIONE SELECTION
RIF.TESTO REFTEXT
RIGHE ROWS
RIMPIAZZA REPLACE
RIPETI REPT
RIPRENDI RESUME
RIPRISTINA.BARRA.DEGLI.STRUMENTI RESET.TOOLBAR
RISULTATO RESULT
ROMANO ROMAN
RQ RSQ
SALVA.BARRA.DEGLI.STRUMENTI SAVE.TOOLBAR
SALVA.DIALOGO SAVE.DIALOG
SCARTO OFFSET
SCEGLI CHOOSE
SCENARIO.INFO SCENARIO.GET
SCHERMO ECHO
SE IF
SECONDO SECOND
SEGNO SIGN
SEN SIN
SENH SINH
SERIE SERIES
SINISTRA LEFT
SINISTRAB LEFTB
SOMMA SUM
SOMMA.DIFF.Q SUMX2MY2
SOMMA.Q SUMSQ
SOMMA.Q.DIFF SUMXMY2
SOMMA.SE SUMIF
SOMMA.SOMMA.Q SUMX2PY2
SOSTITUISCI SUBSTITUTE
SOSTITUISCI.B REPLACEB
STRINGA.ESTRAI MID
SUBTOTALE SUBTOTAL
T T
TAN TAN
TANH TANH
TASSO RATE
TASTO.ANNULLA CANCEL.KEY
TENDENZA TREND
TEST.CHI CHITEST
TEST.F FTEST
TEST.T TTEST
TEST.Z ZTEST
TESTO TEXT
TESTO.RIF TEXTREF
TIPO TYPE
TIR.COST IRR
TIR.VAR MIRR
TITOLO.FINESTRA WINDOW.TITLE
TRONCA TRUNC
TROVA FIND
TROVA.B FINDB
USDOLLAR USDOLLAR
VA PV
VAI.A GOTO
VAL.ERR ISERR
VAL.ERRORE ISERROR
VAL.FUT FV
VAL.LOGICO ISLOGICAL
VAL.NON.DISP ISNA
VAL.NON.TESTO ISNONTEXT
VAL.NUMERO ISNUMBER
VAL.RIF ISREF
VAL.TESTO ISTEXT
VAL.VUOTO ISBLANK
VALORE VALUE
VALORE.RIF DEREF
VALUTA DOLLAR
VALUTA.TESTO EVALUATE
VAN NPV
VAR VAR
VAR.POP VARP
VERO TRUE
VOLATILE VOLATILE

WEIBULL WEIBULL

You might also like