[Résolu][Base] Importer table d'une autre base

Discussions et questions sur tout ce qui concerne la programmation tous langages et tous modules confondus.

Modérateur : Vilains modOOs

Règles du forum
:alerte: Balisage obligatoire dans cette section !
Aidez-nous à vous aider au mieux en balisant correctement votre question : reportez-vous sur les règles de cette section avant de poster !
Piaf
GourOOu
GourOOu
Messages : 5622
Inscription : 25 nov. 2011 18:07
Localisation : Guyane

[Résolu][Base] Importer table d'une autre base

Message par Piaf »

Bonsoir,

Suite à ce fil lier deux tables de deux bases de données existantes
Il n’est effectivement pas possible de lier (attacher) une table d'une base de données à une autre.
Ce pourrait être une fonctionnalité intéressante.

On peut cependant importer une table d'une base à l'autre, et actualiser les données à l'ouverture de la base.
Dans le cadre « pourquoi faire simple quand on peut faire compliquer » :D Je vous propose un petit exemple.

Le principe : à l'ouverture de la base, vérifier que la table soit déjà importée, si elle ne l'est pas, le faire.
Ensuite, ajouter les données de la table origine à la table importée.
Pour ce faire, j'ai adapté quatre macros.
Les deux bases doivent être enregistrées.

Code : Tout sélectionner

Sub OuvertureBase()
Dim Context as Object, BaseManuel as Object
	ThisDatabaseDocument.CurrentController.connect("","")
	maConnexion = ThisDatabasedocument.CurrentController.ActiveConnection
	Context = createUnoService("com.sun.star.sdb.DatabaseContext")
	BaseManuel = Context.getByName("AngebotManuels")
	oConnection = BaseManuel.getConnection("","")
	CreerTable
End Sub
Cette macro est déclenchée à l'ouverture de la base, elle met en place les connexions nécessaires (base courante et la base où l'on va récupérer la table et/ou les données) et appelle la macro CreerTable.

Code : Tout sélectionner

Sub CreerTable()
Dim lesTables As Object, maRequete As Object
Dim instrSQL As String
	lesTables = maConnexion.tables
	If lesTables.hasByName(TblCopie) Then
		instrSQL = "DELETE FROM " & """" & TblCopie & """"
		maRequete = maConnexion.createStatement()
		maRequete.executeUpdate(instrSQL)
		CopierDonneesManuel
	Else
		CopierStructureManuel
	End If
End Sub
Cette macro vérifie si la table existe dans la base courante :
Si Oui, on supprime les données et on appelle la macro CopierDonneesManuel.
Si Non, on appelle la macro CopierStructureManuel.

Code : Tout sélectionner

Sub CopierStructureManuel()
Dim oTables as object
Dim TblDescriptor as object, ColDescriptor as object, Cols as object, Col as object, cleDescriptor As Object
Dim oTables2 as Object
	oTables = oConnection.Tables
	TblDescriptor = oTables.createDataDescriptor
	TblDescriptor.Name = TblCopie
	ColDescriptor =  TblDescriptor.columns.createDataDescriptor
	cleDescriptor = TblDescriptor.Keys.createDataDescriptor
	cleDescriptor.Name = "Principal"
	cleDescriptor.Type = com.sun.star.sdbcx.KeyType.PRIMARY
	Cols = oTables.getByName(TblSource).Columns
	For Each Col In Cols
		ColDescriptor.Name = Col.Name
		ColDescriptor.Type = Col.Type
		ColDescriptor.Precision = Col.Precision
		If Col.isAutoIncrement Then
			TblDescriptor.columns.appendByDescriptor(ColDescriptor)		
			cleDescriptor.Columns.appendByDescriptor(ColDescriptor)
		Else	
			TblDescriptor.columns.appendByDescriptor(ColDescriptor)
		End If	
	Next Col
	oTables2 = maConnexion.Tables
	TblDescriptor.Keys.appendByDescriptor(cleDescriptor)
	oTables2.appendByDescriptor(TblDescriptor)
	MsgBox("Table " & TblSource & " Copiée sous le nom de " & TblCopie,64,"Import de table")
	CopierDonneesManuel
End Sub
Cette macro recopie la structure de la table d'origine dans la table que l'on crée, à l’exception de la valeur auto-incrément pour le champ de la clef primaire. Le même champ sera utilisé en clef primaire dans la table crée mais renseigné lors de l'importation des données (Je pense que c'est plus cohérent).
La macro appelle la macro CopierDonneesManuel

Code : Tout sélectionner

Sub CopierDonneesManuel()
Dim unRowSet As Object, unRowSet2 as Object
	Fenetre =ThisComponent.CurrentController.Frame.ContainerWindow
	Fenetre.Enable = False
	unRowSet = createUnoService("com.sun.star.sdb.RowSet")
	unRowSet2 = createUnoService("com.sun.star.sdb.RowSet")
	With unRowSet2
		.ActiveConnection = maConnexion
		.CommandType = com.sun.star.sdb.CommandType.TABLE
		.Command = tblCopie
		.Execute
	End With		
	On Error GoTo fermerRowSet
	With unRowSet
		.ActiveConnection = oConnection
		.CommandType = com.sun.star.sdb.CommandType.TABLE
		.Command = tblSource
		.Execute
		While .Next
			Identifiant = .Columns.getByName("IdManuel").Int
			LeNom = .Columns.getByName("NomManuel").String
			Annee = .Columns.getByName("AnneeManuel").String
			With unRowSet2
				.moveToInsertRow
				.Columns.getByName("IdManuel").updateInt(Identifiant)
				.Columns.getByName("NomManuel").updateString(LeNom)
				.Columns.getByName("AnneeManuel").updateString(Annee)
				.insertRow
			End With
		Wend
		Fenetre.Enable = True
		UnRowSet2.Dispose
		oConnection.Dispose
		MsgBox("Les données de la table " & TblSource & " ont été copiées dans la table " & TblCopie,64,"Import de table")
Fin:
On Error GoTo 0
.dispose
Exit Sub
fermerRowSet:
MsgBox(Error, 16)
Resume Fin
End With
End Sub
La macro gèle la fenêtre de l'application (pas très convaincant vu le peu de champs et d'enregistrements dans l'exemple, mais sur un nombre plus important de champs et d'enregistrements !.
Ensuite elle boucle sur les enregistrements de la table source et les ajoute à la table destination.
Ferme les RowSet et la connexion à la base distante.

Toutes suggestions ou corrections seront bien sur les bienvenues
A+
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
Dernière modification par Piaf le 26 août 2013 21:48, modifié 1 fois.
Libre Office Version: 6.1.6 et Apache OpenOffice 4.1.6 Sur Xubuntu 18.04 AMD64
Piaf
GourOOu
GourOOu
Messages : 5622
Inscription : 25 nov. 2011 18:07
Localisation : Guyane

Re: [Base] Importer table d'une autre base

Message par Piaf »

Bonsoir

Pour aller un peu plus loin dans l'import de données dans base, je vous propose l'import d'un fichier csv.
Ce type de manipulation peut être utile dans le cas de réceptions régulières d'un ou de plusieurs fichiers de même structure.

La base exemple se contente d'importer les données d'un fichier, mais on pourrait envisager, un ajout, une mise à jour, l'import de plusieurs fichiers à mettre en relation, etc.

Il est indispensable de connaître la structure du fichier.

À partir de la structure du fichier, on crée la table dans Base.
La table créée, on met en place les procédures.
La macro OuvertureBase est déclenchée à l'ouverture de la base.

Code : Tout sélectionner

Sub OuvertureBase
Dim DrvMan As Object, maRequete as Object
Dim cheminCSV As String, URLbdcsv As String, instrSQL as String
Dim Infos(3) As New com.sun.star.beans.PropertyValue
	ThisDatabaseDocument.CurrentController.connect("","")
	maConnexion = ThisDatabasedocument.CurrentController.ActiveConnection
	OuvrirAttente()
	DrvMan = CreateUnoService("com.sun.star.sdbc.DriverManager")
	cheminCSV = SelectCSV
	URLbdcsv = "sdbc:flat:" & cheminCSV
	Infos(0).Name = "HeaderLine"
	Infos(0).Value = True
	Infos(1).Name = "FieldDelimiter"
	Infos(1).Value = chr(32)
	Infos(2).Name = "StringDelimiter"
	Infos(2).Value = """"
	Infos(3).Name = "Extension"
	Infos(3).Value = "csv"
	oConnexion = DrvMan.getConnectionWithInfo(URLbdcsv, Infos())
	instrSQL = "DELETE FROM  ""tAdherents"""
	maRequete = maConnexion.createStatement()
	maRequete.executeUpdate(instrSQL)
  	CopierDonnees
End Sub
Elle permet de sélectionner le fichier csv, établie les connexions, supprime les données existantes de la table.
La connexion au fichier csv nécessite de connaître sa structure. Les objets utilisables par ce type de connexion ont moins de propriétés que ceux d'une base classique.
La macro enfin appelle CopierDonnees.

Code : Tout sélectionner

Sub CopierDonnees
On Error GoTo CopierDonnees_Err
Dim unRowSet as Object, maRequete as Object, resuQuery as Object, maRequete2, Resultat as Object
Dim Fenetre as Object, FenetreForm as Object, avance as Object
Dim instrSQL as String, instrSQL2 as String, i as Integer, dteNaiss as Date, Compte as Integer, x as Integer
	Fenetre = ThisDatabaseDocument.CurrentController.Frame.ContainerWindow
	FenetreForm = oForm.currentcontroller.Frame.ContainerWindow
	Fenetre.Enable = False
	FenetreForm.Enable = False
	avance = oForm.CurrentController.StatusIndicator
	unRowSet = createUnoService("com.sun.star.sdb.RowSet")
	instrSQL = "SELECT * FROM ""tAdherents"" ORDER BY ""IdAdh"" "
	instrSQL2 = "SELECT COUNT(*) as ""nb"" FROM ""tAdherents"""
	maRequete = oConnexion.createStatement()
	maRequete2 = oConnexion.createStatement()
	Resultat = maRequete2.executeQuery(instrSQL2)
	Resultat.Next
	Compte = resultat.getInt(1)
	resuQuery = maRequete.executeQuery(instrSQL)
	With unRowSet
		.ActiveConnection = maConnexion
		.CommandType = com.sun.star.sdb.CommandType.TABLE
		.Command = "tAdherents"
		.Execute
		x = 1
		avance.start("Veuillez patienter ...", Compte)
		Do While resuQuery.Next
			.moveToInsertRow
			For i = 1 to 10
				Select Case .Columns.getByIndex(i -1).TypeName
					Case "INTEGER"
						.Columns.getByIndex(i -1).updateInt(resuQuery.getInt(i))
					Case "VARCHAR"
						.Columns.getByIndex(i -1).updateString(resuQuery.getString(i))
					Case "DATE"
						dteNaiss = CDate(resuQuery.getString(i))
						.Columns.getByIndex(i -1).updateDate(DateTodbDate(dteNaiss))
				End Select
				If i = 1 Then
					.insertRow
				Else
					.UpdateRow
				End If	
    		Next i
			avance.Value = x
			avance.Text = "Ligne " & x & " recopiée" 
			x = x + 1 		   		
  		Loop
  		avance.Text = "Terminé " & Compte & " lignes recopiées"
  	End With
	oConnexion.Dispose
	unRowSet.Dispose
	Wait 800
	avance.End
	FenetreForm.Enable = True
	Fenetre.Enable = True 
	ThisDatabaseDocument.FormDocuments.getByName( "Formulaire" ).Close
CopierDonnees_Exit:	
	On Error GoTo 0
	Exit Sub
CopierDonnees_Err:
	MsgBox(Error, 16)
	FenetreForm.Enable = True
	Fenetre.Enable = True
	oConnexion.Dispose
	unRowSet.Dispose
	Resume CopierDonnees_Exit		
End Sub
La macro recopie les données du fichier dans la table. Comme la recopie se fait champ par champ, les fenêtres sont désactivées et l'avancement de la procédure est affiché.

L'import de données issues de Calc peut se faire de la même manière.

Code : Tout sélectionner

Sub OuvertureBase
Dim DrvMan As Object
Dim cheminCalc As String, URLbdCalc As String, instrSQL as String
Dim Infos() As New com.sun.star.beans.PropertyValue
	ThisDatabaseDocument.CurrentController.connect("","")
	maConnexion = ThisDatabasedocument.CurrentController.ActiveConnection
	DrvMan = CreateUnoService("com.sun.star.sdbc.DriverManager")
	cheminCalc = SelectCalc
	URLbdCalc = "sdbc:calc:" & cheminCalc
	oConnexion = DrvMan.getConnectionWithInfo(URLbdCalc, Infos())
End Sub
Le pilote est de de type sdbc:calc et n'a pas besoin de la structure du fichier, le tableau Infos est donc un tableau vide.

Pour l'export, si c'est vous qui faites la mise à jour, voir [Base] Export en CSV
A+
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
Libre Office Version: 6.1.6 et Apache OpenOffice 4.1.6 Sur Xubuntu 18.04 AMD64
Piaf
GourOOu
GourOOu
Messages : 5622
Inscription : 25 nov. 2011 18:07
Localisation : Guyane

Re: [Résolu][Base] Importer table d'une autre base

Message par Piaf »

Bonsoir
Après un peu de travail (quand même :lol: )
Base dispose d'une fonctionnalité beaucoup plus simple que l'exemple précédent pour attacher un fichier csv à une base de données.
Malheureusement la page Tables texte pour la version HSQLDB de Base a été effacée. Mais la documentation (en anglais (of course) ) est valable pour la version actuelle d'HSQL Chapter 5. Text Tables.
En résumé et en français.
Piaf a écrit :Il est indispensable de connaître la structure du fichier.
Toujours d'actualité.
On créer la structure d'une table Texte vide, en fonction du fichier csv.
Exemple pour le fichier csv joint.

Code : Tout sélectionner

CREATE TEXT TABLE "Adherents" ("IdAdh" INTEGER PRIMARY KEY,"Titre" VARCHAR(5), "Nom" VARCHAR(20), "Prenom" VARCHAR(20),"DateNaiss" VARCHAR(10)," Adresse" VARCHAR(50),"CP" VARCHAR(5),"Ville" VARCHAR(50),"Tph" VARCHAR(14),"Email" VARCHAR(50));
Instruction SQL à exécuter dans la fenêtre Outils > SQL.
Une fois l'instruction exécutée : Menu Affichage > Actualiser les tables, la structure de la table que vous venez de créer s'affiche.
On va maintenant attacher le fichier csv à la table créée.

Code : Tout sélectionner

SET TABLE "Adherents" SOURCE "tAdherents.csv;ignore_first=true;encoding=UTF-8";
  • NB :
  • le fichier csv doit être dans le même répertoire que la base de données.
  • Les dates doivent être au format ISO 1999-12-31 d'où l'import en format texte.
    Pour avoir des dates dans une requête:
    TxtEnDate.png
  • Le séparateur décimal doit être le point.
Pour explorer un peu plus ces fonctionnalités voir : [Example] Loading CSV into preformatted spreadsheets
A+
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
Libre Office Version: 6.1.6 et Apache OpenOffice 4.1.6 Sur Xubuntu 18.04 AMD64
Avatar de l’utilisateur
jeanmimi
Grand Maître de l'OOffice
Grand Maître de l'OOffice
Messages : 17219
Inscription : 03 mars 2006 16:02
Localisation : Venise verte

Re: [Résolu][Base] Importer table d'une autre base

Message par jeanmimi »

Piaf a écrit :Malheureusement la page Tables texte pour la version HSQLDB de Base a été effacée.
Elle semble subsister ici :
http://wiki.openoffice.org/wiki/FR/Docu ... Guide/ch06
LibreOffice : Version : 25.8.4 (x64)(23 février 2026)
Adoptium JRE ou Oracle JRE (x64), Windows 10, Thunderbird, Firefox
Piaf
GourOOu
GourOOu
Messages : 5622
Inscription : 25 nov. 2011 18:07
Localisation : Guyane

Re: [Résolu][Base] Importer table d'une autre base

Message par Piaf »

Bonsoir
Merci pour le lien. C'est quand même mieux en français.
Je constate en plus que la question avait déjà été traitée par plus qualifiés que moi. [Résolu] Liaison dynamique avec un fichier .csv
A+
Libre Office Version: 6.1.6 et Apache OpenOffice 4.1.6 Sur Xubuntu 18.04 AMD64