Excel et importation de CSV

Bonjour à tous !

Dans la boite où je suis en stage, ils bossent avec une machine qui très bêtement enregistre des températures à intervalle régulier dans une carte mémoire, au format csv. Jusque là on se dit que ça va aller pour le repasser sous Excel et pouvoir tracer un beau graphique de la température. Las!
Ladite machine, au lieu d’enregistrer les données en colonnes, les dispose en ligne donc avec une colonne par valeur. Or Excel est limité à 256 colonnes maximum. Et là bien sur, c’est le drame : impossible d’importer toutes les données dans la feuille Excel, seules les 256 premières le sont, ce qui est logique.
La solution, ça serait de pouvoir demander à Excel de transposer à la volée au moment de l’importation pour que les colonnes deviennent lignes et vice-versa (vu qu’on aura jamais plus de 65000 valeurs, ça tiendra très facilement dans ce sens là dans le tableau). Mais soit cette option n’existe pas, ou alors je ne suis pas tombé dessus.
Toujours est-il que si quelqu’un a une idée pour résoudre ce problème, je suis preneur.

Pour information, un exemple de fichier produit par la machine ici.

J’avais eu ce problème pour un fichier une fois.
J’avais donc réolu à l’arrache :
avec un editeur hexa quelqonque, un rehchercher/remplacer/tous ton “;” (ou " " , ou …) par le retour chariot.
Après importation sous excel sans PB.

Bon je viens de le faire, Y a des subtilités :
le retour chariot fat 2 caracére (0D0A ), la virgule un seul. un rech/rempl “,” par “,” regle probleme.

Apres sous excel, ya tout en lignes mais ca se remet bien avec des formule simple dans les colones B et suivantes ( type b1 = A3000 )

Si c est juste pour avoir le grafe tu peux utiliser matlab ou scilab (variante libre dev par l INRIA)

Si non le find and replace ca marche aussi.

Koubiak

J’y avais pensé, mais le soucis c’est que la machine enregistre en fait plusieurs températures et que cette solution me ferait une seule colonne en vrac. Et ça impose d’éditer les fichiers avec un logiciel qu’ils ne voudront pas forcément installer dans l’entreprise.
L’idéal ça serait un truc automatique sous Excel (macro ?).

Tu fais un macro word alors … avec une boucle sur le nombre d arguments enregistrés…

Koubiak qui a honte

Je ne connais pas bien les API d’excel mais je m’en tirais souvent en utilisant le menu Outils/macro/nouvelle macro qui génère du VBA excel avec ce qu’on fait à la main. [ol]
[li]je débute l’enregistrement[/li][li]dans les lignes A1 à E1 j’écris a,b,c,d,e[/li][li]je fais copier[/li][li]je change de feuille[/li][li]je fais édition/“collage spécial”/transposé[/li][/ol]Et voilà ce que j’obtiens:
[codebox]Sub Macro1()

’ Macro1 Macro
’ Macro enregistrée le 26/04/2006 par x

'
ActiveCell.FormulaR1C1 = "a"
Range(“B1”).Select
ActiveCell.FormulaR1C1 = "b"
Range(“C1”).Select
ActiveCell.FormulaR1C1 = "c"
Range(“D1”).Select
ActiveCell.FormulaR1C1 = "d"
Range(“E1”).Select
ActiveCell.FormulaR1C1 = "e"
Range(“A1:E1”).Select
Range(“E1”).Activate
Selection.Copy
Sheets(“Feuil2”).Select
Selection.PasteSpecial Paste:=xlAll, Operation:=xlNone, SkipBlanks:=False _
, Transpose:=True
End Sub
[/codebox]

voilà ça peut te donner une base de départ

Wai bien sur en macro y’a moyen de le faire, mais ça m’étonne qu’il y ait pas une option pour inverser ligne et colonne directement à l’import parce que ça me semble juste super pratique donc assez indispensable.
Bon sinon tant pis, je vais me coller à la macro, en maudissant le constructeur de cette machine de sauvegarder ces données dans ce format.

Pendant ce temps au forum SegFault : http://www.cafzone.net/ipb/index.php?showtopic=31998

Et voici le script modifié par mes soins pour importer ton fichier, il fonctionne mais comporte certaines limites : le nombre de lignes doit être inférieur à 50, et le nombre données doit être inférieur à 65535. Je te laisse le modifié si tu veux corriger ces limites.

ImportCSV.au3
[codebox]
#cs

Import CSV File

Developped by Dreux Loic

Version 1.1

#ce

#include “Include/Functions.au3”
#include “Include/File.au3”

Opt(“MustDeclareVars”, 1)
Opt(“GUIOnEventMode”, 1)

; Composant COM
local $excel, $classeur
; Gestion Fichiers
local $fodResultat, $fichier, $tailleFichier
; Composants Graphiques
local $barProgression, $boutonAnnuler, $libelle
; Timer
local $timerDebut
; Declaration des lignes et colonnes
local $lignes, $ligne, $splLigne, $nbColonnes
; Compteurs
local $cmpLigne, $cmpFeuille, $i, $progression

; Ouverture de l’objet Com Excel
$excel = ObjCreate (“Excel.Application”)
if @error then
Msgbox (0x10, “Importation de CSV”, “Microsoft Excel n’est pas installé, veuillez l’installer avant d’exécuter ce script”)
$excel.Quit
exit
endif

; Affichage de la boite de dialogue
$fodResultat = FileOpenDialog(“Importer un CSV dans Excel”, @MyDocumentsDir, “Fichier CSV (.csv;.txt)”, 2)
If @error Then
$excel.Quit
exit
EndIf

; On crée la fenêtre
GUICreate(“Import CSV”, 400, 60)
$barProgression = GUICtrlCreateProgress(2,5,396,20)
$boutonAnnuler = GUICtrlCreateButton("&Annuler", 160, 30, 80, 25)
$libelle = GUICtrlCreateLabel("",10,38,150,25)
GUICtrlSetOnEvent($boutonAnnuler, “Annuler”)
GUISetState (@SW_SHOW)

; On configure excel
$excel.DisplayAlerts = False
$excel.ScreenUpdating = False

; Ouverture des fichiers en entrée et en sortie
$classeur = $excel.workbooks.add ; Add a new workbook
$fichier = FileOpen($fodResultat, 0)
If $fichier = -1 Then
MsgBox(0x10, “Importation de CSV”, “Impossible de lire le fichier”)
$excel.Quit
Exit
EndIf
$tailleFichier = FileGetSize ($fodResultat)

; Debut de calcul du temps
$timerDebut = TimerInit()

; Initialisation des compteurs
$cmpLigne = 0
$cmpFeuille = 1
$progression = 0

; Configuration de la feuille
$classeur.ActiveSheet.Cells.NumberFormat = “@”

; Traitement de la première ligne
$ligne = FileReadLine($fichier)
if @error Then
MsgBox (0x10, “Importation de CSV”, “Impossible de lire le fichier”)
FileClose($fichier)
$excel.Quit
Exit
EndIf
$splLigne = StringSplit($ligne, “,”)
$nbColonnes = 0
Dim $lignes[50][65536]
for $i = 0 to ubound($splLigne) - 2
$lignes[0][$i] = $splLigne[$i+1]
next
$cmpLigne += 1

; On parcours le fichier en entrée
While 1
$nbColonnes = $nbColonnes + 1

; Lecture de la ligne
$ligne = FileReadLine($fichier)
if @error Then
	ExitLoop
endif

; On charge le tableau
$splLigne = StringSplit($ligne, ",")
for $i = 0 to ubound($splLigne) - 2
	$lignes[$cmpLigne][$i] = $splLigne[$i+1]
next
$cmpLigne += 1

; On affiche la progression
$progression = $progression + StringLen($ligne) 
if mod($cmpLigne, 1000) = 0 then 
	GUICtrlSetData ($barProgression, $progression * 100 / $tailleFichier)
	GUICtrlSetData ($libelle, Int(($cmpLigne + (($cmpFeuille - 1) * 65536)) / 1000)  & "000 Lignes importées")
EndIf

; On passe à la feuille suivant
If $cmpLigne = 65536 Then
	GUICtrlSetData ($libelle, "Copie des lignes")
	$classeur.ActiveSheet.Range("A1:" & _NumeroColonneVersChaine($nbColonnes) & $cmpLigne).Value = $lignes
    $cmpLigne = 0
    $cmpFeuille += 1
	Dim $lignes[$nbColonnes][65536]
	
    $classeur.Worksheets($cmpFeuille).Activate
	$classeur.ActiveSheet.Cells.NumberFormat = "@"
EndIf

Wend
GUICtrlSetData ($barProgression, 100)
GUICtrlSetData ($libelle, “Copie des lignes”)
$classeur.ActiveSheet.Range(“A1:” & _NumeroColonneVersChaine($cmpLigne) & $splLigne[0]).Value = $lignes

; Fermeture du fichier
FileClose($fichier)

; On affiche Excel
$excel.ScreenUpdating = True
$excel.Visible = 1
$excel.StatusBar = "Temps d’exécution : " & _FormaterDuree(TimerDiff($timerDebut))

Exit

#cs

Annuler()

#ce
Func Annuler()
FileClose($fichier)
$excel.Quit
Exit
EndFunc
[/codebox]

Include/File.au3
[codebox]
#include-once

; ------------------------------------------------------------------------------
;
; AutoIt Version: 3.0
; Language: English
; Description: Functions that assist with files and directories.
;
; ------------------------------------------------------------------------------

;===============================================================================

;
; Description: Returns the number of lines in the specified file.
; Syntax: _FileCountLines( $sFilePath )
; Parameter(s): $sFilePath - Path and filename of the file to be read
; Requirement(s): None
; Return Value(s): On Success - Returns number of lines in the file
; On Failure - Returns 0 and sets @error = 1
; Author(s): Tylo tylo@start.no
; Note(s): It does not count a final @LF as a line.
;
;===============================================================================

Func _FileCountLines($sFilePath)
Local $N = FileGetSize($sFilePath) - 1
If @error Or $N = -1 Then Return 0
Return StringLen(StringAddCR(FileRead($sFilePath, $N))) - $N + 1
EndFunc ;==>_FileCountLines

;===============================================================================

;
; Description: Creates or zero’s out the length of the file specified.
; Syntax: _FileCreate( $sFilePath )
; Parameter(s): $sFilePath - Path and filename of the file to be created
; Requirement(s): None
; Return Value(s): On Success - Returns 1
; On Failure - Returns 0 and sets:
; @error = 1: Error opening specified file
; @error = 2: File could not be written to
; Author(s): Brian Keene brian_keene@yahoo.com
; Note(s): None
;
;===============================================================================

Func _FileCreate($sFilePath)
;==============================================
; Local Constant/Variable Declaration Section
;==============================================
Local $hOpenFile
Local $hWriteFile

$hOpenFile = FileOpen($sFilePath, 2)

If $hOpenFile = -1 Then
	SetError(1)
	Return 0
EndIf

$hWriteFile = FileWrite($hOpenFile, "")

If $hWriteFile = -1 Then
	SetError(2)
	Return 0
EndIf

FileClose($hOpenFile)
Return 1

EndFunc ;==>_FileCreate

;===============================================================================

;
; Description: Reads the specified file into an array.
; Syntax: _FileReadToArray( $sFilePath, $aArray )
; Parameter(s): $sFilePath - Path and filename of the file to be read
; $aArray - The array to store the contents of the file
; Requirement(s): None
; Return Value(s): On Success - Returns 1
; On Failure - Returns 0 and sets @error = 1
; Author(s): Jonathan Bennett
; Note(s): None
;
;===============================================================================

Func _FileReadToArray($sFilePath, ByRef $aArray)
;==============================================
; Local Constant/Variable Declaration Section
;==============================================
Local $hFile

$hFile = FileOpen($sFilePath, 0)

If $hFile = -1 Then
	SetError(1)
	Return 0
EndIf

$aArray = StringSplit( FileRead($hFile, FileGetSize($sFilePath)), @LF)

FileClose($hFile)
Return 1

EndFunc ;==>_FileReadToArray

;===============================================================================

;
; Description: Writes the specified text to a log file.
; Syntax: _FileWriteLog( $sLogPath, $sLogMsg )
; Parameter(s): $sLogPath - Path and filename to the log file
; $sLogMsg - Message to be written to the log file
; Requirement(s): None
; Return Value(s): On Success - Returns 1
; On Failure - Returns 0 and sets:
; @error = 1: Error opening specified file
; @error = 2: File could not be written to
; Author(s): Jeremy Landes jlandes@landeserve.com
; Note(s): If the text to be appended does NOT end in @CR or @LF then
; a DOS linefeed (@CRLF) will be automatically added.
;
;===============================================================================

Func _FileWriteLog($sLogPath, $sLogMsg)
;==============================================
; Local Constant/Variable Declaration Section
;==============================================
Local $sDateNow
Local $sTimeNow
Local $sMsg
Local $hOpenFile
Local $hWriteFile

$sDateNow = @YEAR & "-" & @MON & "-" & @MDAY
$sTimeNow = @HOUR & ":" & @MIN & ":" & @SEC
$sMsg = $sDateNow & " " & $sTimeNow & " : " & $sLogMsg

$hOpenFile = FileOpen($sLogPath, 1)

If $hOpenFile = -1 Then
	SetError(1)
	Return 0
EndIf

$hWriteFile = FileWriteLine($hOpenFile, $sMsg)

If $hWriteFile = -1 Then
	SetError(2)
	Return 0
EndIf

FileClose($hOpenFile)
Return 1

EndFunc ;==>_FileWriteLog

;===============================================================================

;
; Function Name: _TempFile()
; Description: Generate a name for a temporary file. The file is guaranteed
; not to already exist in the user’s %TEMP% directory.
; Parameter(s): None.
; Requirement(s): None.
; Return Value(s): Filename of a temporary file which does not exist.
; Author(s): Dale (Klaatu) Thompson
; Notes: None.
;
;===============================================================================

Func _TempFile()
Local $s_TempName

Do
$s_TempName = "~"
While StringLen($s_TempName) < 8
$s_TempName = $s_TempName & Chr(Round(Random(97, 122), 0))
Wend
$s_TempName = @TempDir & “” & $s_TempName & ".tmp"
Until Not FileExists($s_TempName)
Return ($s_TempName)
EndFunc

[/codebox]

Include/Functions.au3
[codebox]
#include-once

; ------------------------------------------------------------------------------
;
; Language: French
; Description: Fonctions courantes
;
; ------------------------------------------------------------------------------

Opt(“MustDeclareVars”, 1)

;===============================================================================

;
; Function Name: _FormaterDuree()
; Description: Formate une durée
; Parameter(s): $milliSeconde - Durée en milliSeconde
; Requirement(s): None.
; Return Value(s): Une chaine de caractères formatée
; Author(s): Loïc Dreux
;
;===============================================================================

Func _FormaterDuree($milliSeconde)
local $seconde, $minute, $heure

$seconde = Int($milliSeconde / 1000)
$minute = Int($seconde / 60)
$seconde = mod($seconde, 60)
$heure = Int($minute / 60)
$minute = mod($minute, 60)
$heure = mod($heure, 24)

return _CompleterChaineG($heure, "0", 2) & ":" & _CompleterChaineG($minute, "0", 2) & ":" & _CompleterChaineG($seconde, "0", 2)

EndFunc

;===============================================================================

;
; Function Name: _CompleterChaineG()
; Description: Complète une chaine par la gauche
; jusqu’à un certain nombre de caractères
; Parameter(s): $chaine - Chaine de caractères initiale
; $pad - Caractère à utiliser pour compléter la chaine
; $taille - Taille de la chaine finale
; Requirement(s): None.
; Return Value(s): Une chaine de caractères
; Author(s): Loïc Dreux
;
;===============================================================================

Func _CompleterChaineG($chaine, $pad, $taille)
While StringLen($chaine) < $taille
$chaine = $pad & $chaine
Wend
return $chaine
EndFunc

;===============================================================================

;
; Function Name: _CompleterChaineD()
; Description: Complète une chaine par la droite
; jusqu’à un certain nombre de caractères
; Parameter(s): $chaine - Chaine de caractères initiale
; $pad - Caractère à utiliser pour compléter la chaine
; $taille - Taille de la chaine finale
; Requirement(s): None.
; Return Value(s): Une chaine de caractères
; Author(s): Loïc Dreux
;
;===============================================================================

Func _CompleterChaineD($chaine, $pad, $taille)
While StringLen($chaine) < $taille
$chaine = $chaine & $pad
Wend
return $chaine
EndFunc

;===============================================================================

;
; Function Name: _NumeroColonneVersChaine()
; Description: Retourne le numéro de colonne ‘Excel’ sous forme de chaine
; Parameter(s): $numeroCol - Numéro de colonne sous forme numérique
; Requirement(s): None.
; Return Value(s): Une chaine de caractères
; Author(s): Loïc Dreux
;
;===============================================================================

Func _NumeroColonneVersChaine($numeroCol)
local $i, $j

$numeroCol = $numeroCol - 1

$j = mod($numeroCol, 26)
$i = ($numeroCol - $j) / 26

If $i > 0 Then
	return  Chr(64 + $i) & Chr(65 + $j)
Else
	return Chr(65 + $j)
EndIf

EndFunc
[/codebox]