I. Introduction▲
Il peut être utile de lire des données provenant d'Excel dans le cas d'appareils de mesure ou de machines de test générant des fichiers résultats sous format Excel.
Cet article se base sur les articles précédents de la série. Leur lecture préalable est donc fortement conseillée.
II. Lecture des données▲
II-A. Type de données▲
Les valeurs sont lues dans des cellules Excel en récupérant la propriété Value de l'objet Range qui contient l'adresse de ces cellules.
Depuis MATLAB, il est possible de lire des données numériques, des chaînes de caractères ou encore des valeurs booléennes.
Soit trois cellules contenant ces trois types de données :
Le code suivant permet de récupérer les trois valeurs :
num = ActiveSheet.Range('B2'
).Value;
str = ActiveSheet.Range('C2'
).Value;
bool = ActiveSheet.Range('D2'
).Value;
donne :
>> num
num =
1.2500
>> str
str =
MATLAB
>> bool
bool =
1
On peut également utiliser la fonction whos pour vérifier la classe de ces variables :
>> whos x str bool
Name Size Bytes Class Attributes
bool 1x1 1 logical
str 1x6 12 char
num 1x1 8 double
II-B. Lecture de valeurs numériques▲
Il est souvent nécessaire d'importer plusieurs valeurs simultanément.
Les dimensions du tableau obtenu sont les mêmes que celles de la plage utilisée avec l'objet Range.
Si plusieurs valeurs sont lues, elles sont obligatoirement stockées dans un tableau de cellules et ce, même si elles sont de même type.
Prenons l'exemple de la feuille de calcul ci-dessous :
Voici trois lignes de code qui récupèrent respectivement la première ligne du tableau, la première colonne du tableau et le tableau en entier :
>> R = ActiveSheet.Range('B2:D2'
).Value;
>> C = ActiveSheet.Range('B2:B4'
).Value;
>> M = ActiveSheet.Range('B2:D4'
).Value;
Intéressons-nous dans un premier temps à la classe de ces variables :
>> whos R C M
Name Size Bytes Class Attributes
C 3x1 360 cell
M 3x3 1080 cell
R 1x3 360 cell
Les variables R, C et M sont donc bien des tableaux de cellules.
Pour les convertir en tableaux numériques, on utilise la fonction cell2mat :
>> R = cell2mat(R)
R =
8 1 6
>> C = cell2mat(C)
C =
8
3
4
>> M = cell2mat(M)
M =
8 1 6
3 5 7
4 9 2
Les variables ont bien changé de classe :
>> whos R C M
Name Size Bytes Class Attributes
C 3x1 24 double
M 3x3 72 double
R 1x3 24 double
II-C. Lecture de chaînes de caractères▲
Si le contenu de plusieurs cellules contenant des chaînes de caractères est lu simultanément, les valeurs sont stockées dans un tableau de cellules.
Soit la feuille de calcul suivante :
On peut lire ces trois valeurs avec le code suivant :
>> X = ActiveSheet.Range('B2:D2'
).Value;
Ce qui retourne bien:
>> X
X =
'AAA'
'MATLAB'
'CCC'
II-D. Lecture de données hétérogènes▲
Il est également possible de lire des valeurs de types différents en une seule fois. Elles seront alors stockées dans un tableau de cellules.
L'exemple du chapitre I-A :
num = ActiveSheet.Range('B2'
).Value;
str = ActiveSheet.Range('C2'
).Value;
bool = ActiveSheet.Range('D2'
).Value;
aurait pu s'écrire :
X = ActiveSheet.Range('B2:D2'
).Value;
II-E. Lecture de dates▲
Sous Excel, les dates sont soit écrites sous forme de chaînes de caractères, soit sous forme série.
La lecture dans le premier cas ne pose aucun souci. Dans le second cas, il faut tenir compte des différences d'interprétation entre Excel et MATLAB (voir l'article Limites).
III. Exemples▲
Reprenons l'exemple utilisé dans le chapitre III de l'article Écriture de données et mise en forme.
Vous trouverez le fichier Excel obsFrance.xlsx ici.
Pour rappel, le classeur contient des relevés de températures pour différentes villes françaises fournis par Météo France à cette adresse http://france.meteofrance.com/france/observations.
III-A. Lecture globale▲
function
[villes, echeances, temperatures] = obsFrance2matlab
% Ouverture de l'application Excel
Excel = actxserver('Excel.Application'
);
Excel.Visible = false;
% Chemin du classeur à ouvrir
xlspath = pwd ;
xlsfile = 'obsFrance.xlsx'
;
% Ouverture du classeur
Workbook = Excel.Workbooks.Open(fullfile(xlspath,xlsfile));
% Récupération de la première feuille de calcul dans la variable
% Activesheet pour simplifier le code par la suite
ActiveSheet = Excel.Worksheets.Item('Températures'
);
% Récupération du nom des villes grâce à la plage nommée 'villes'
villes = ActiveSheet.Range('villes'
).Value;
% Prise en compte du décalage pour les dates
if
Workbook.Date1904
incr = datenum('01-Jan-1904 00:00:00'
);
else
incr = datenum('30-Dec-1899 00:00:00'
);
end
% Récupération des dates des relevés
r(1) = ActiveSheet.Range('C5'
);
r(2) = ActiveSheet.Range('C5'
).End('xlToRight'
);
echeances = ActiveSheet.get('Range'
,r(1),r(2)).Value;
echeances = cell2mat(echeances)+incr;
% Récupération des températures
r(1) = ActiveSheet.Range('C6'
);
r(2) = ActiveSheet.Range('C6'
).End('xlToRight'
).End('xlDown'
);
temperatures = ActiveSheet.get('Range'
,r(1),r(2)).Value;
temperatures = cell2mat(temperatures);
% Fermeture du classeur
Workbook.Close(false);
% Fermeture de l'application Excel
Quit(Excel);
Voici le résultat de l'exécution de ce code :
>> [villes, echeances, temperatures] = obsFrance2matlab;
>> whos villes echeances temperatures
Name Size Bytes Class Attributes
echeances 1x24 192 double
temperatures 40x24 7680 double
villes 40x1 5446 cell
III-B. Lecture ciblée▲
Supposons maintenant qu'on veuille récupérer les valeurs pour une seule ville en ne connaissant que son nom et non pas sa position dans la feuille.
On peut par exemple utiliser la méthode Find de l'objet Range.
Le code suivant récupère les valeurs pour la ville de Toulouse :
ville = 'Toulouse-Blagnac'
;
range = ActiveSheet.Range('villes'
);
address = range.Find(ville).Address;
r(1) = ActiveSheet.Range(address).get('Cells'
, 1, 2);
r(2) = r(1).End('xlToRight'
);
data = ActiveSheet.get('Range'
, r(1), r(2)).Value;
data = cell2mat(data);
ce qui retourne bien :
data =
Columns 1 through 12
4.6000 5.5000 8.8000 11.3000 8.8000 6.9000 9.0000 6.8000 0.9000 0.4000 7.5000 8.2000
Columns 13 through 24
4.1000 4.5000 5.7000 6.0000 5.2000 4.1000 3.3000 3.2000 2.9000 5.9000 6.6000 5.0000
IV. Comparaison avec xlsread▲
Voici le code équivalent à celui du chapitre III-A avec la fonction xlsread :
function
[villes, echeances, temperatures] = obsFrance2matlab2
xlspath = pwd ;
xlsfile = 'obsFrance.xlsx'
;
[pasbesoin,villes] = xlsread(fullfile(xlspath,xlsfile),'Températures'
,'B6:B45'
);
echeances = xlsread(fullfile(xlspath,xlsfile),'Températures'
,'C5:Z5'
);
temperatures = xlsread(fullfile(xlspath,xlsfile),'Températures'
,'C6:Z45'
);
Ce code présente trois inconvénients que nous allons développer dans les chapitres suivants.
IV-A. Définition des plages de cellules▲
Le premier inconvénient est qu'il est nécessaire de passer par le style A1 pour spécifier les plages de cellules. Ce qui, comme on l'a vu dans l'article Les plages de cellules est assez peu pratique. Il est également nécessaire de connaître les limites des plages de données avant l'importation dans MATLAB. Dans le cas contraire, toutes les données sont importées.
Alors qu'avec Automation, les propriétés Resize, Cells et End de l'objet Range nous permettent de les définir dynamiquement.
IV-B. Temps d'exécution▲
Il est judicieux ensuite de comparer les temps d'exécution des deux méthodes.
Voici la fonction utilisée pour la comparaison :
function
[t,m,s] = bench_obsFrance2matlab
for
n = 1:5
tic
[villes, echeances, temperatures] = obsFrance2matlab;
t(n,1) = toc;
clear villes echeances temperatures
tic
[villes, echeances, temperatures] = obsFrance2matlab2;
t(n,2) = toc;
clear villes echeances temperatures
end
m = mean(t);
s = m(2)/m(1);
Et voici les résultats :
t =
0.6182 1.5056
0.4865 1.4434
0.4852 1.4750
0.5105 1.4474
0.4943 1.4436
m =
0.5189 1.4630
s =
2.8193
La méthode avec Automation est presque trois fois plus rapide.
Comme nous l'avons déjà vu, la fonction xlsread utilise elle aussi la méthode à base d'Automation pour connecter Excel et MATLAB. La différence du temps d'exécution vient qu'à chaque appel à xlsread , la connexion est ouverte et fermée. Et comme c'est une opération extrêmement coûteuse en temps, le temps global est donc plus long qu'avec notre code où une seule ouverture et fermeture sont effectuées.
IV-C. Lecture partielle▲
Pour finir, la lecture ciblée n'est pas possible avec xlsread. Cela signifie que vous êtes obligés de lire l'intégralité des valeurs et de faire la recherche sous MATLAB. Cela encombre inutilement l'espace de travail, augmente la quantité de mémoire nécessaire pendant la lecture et augmente le temps de calcul.
V. Conclusion▲
Vous savez maintenant comment lire efficacement des données contenues dans une feuille Excel à partir de MATLAB.
Vous savez également que la méthode à base d'Automation est extrêmement souple et rapide.