IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Import fichier excel avec un login différent


Sujet :

VB.NET

  1. #1
    Futur Membre du Club
    Inscrit en
    Février 2011
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 15
    Points : 8
    Points
    8
    Par défaut Import fichier excel avec un login différent
    Bonjour,

    Je dois réaliser une application permettant d'importer des données situées dans un fichier Excel dans une base de données SQLServer.

    Rien de bien compliqué sauf que ma contrainte est la suivante : la personne lançant l'utilitaire d'importation n'a pas accès au répertoire où se trouve le fichier excel à importer.

    Un utilisateur a été spécialement créé pour accéder au répertoire stockant les fichiers Excel à importer. L'idée est donc que mon utilitaires accède à ce répertoire en utilisant ce compte.

    Cela marche bien. J'arrive à lister des fichiers, faire des copies... alors que mon propre login n'a pas accès au répertoire. Le problème intervient lorsque je demande Excel d'ouvrir mon fichier à traiter. J'ai le message "droits insuffisants".

    Je suppose donc qu'Excel se sert de la session windows plutôt que mon login de substitution.

    Est-il possible de demander à excel d'utiliser un utilisateur particulier plutôt que celui de la session en cours ?

    Ou bien est-il possible de traiter mon fichier excel sans passer par excel ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
     
    Imports System.DirectoryServices
    Imports System.Security.Principal
    Imports System.Runtime.InteropServices
    Imports Microsoft.Office.Interop
    Imports System.IO
    Imports System.Transactions
     
    Public Class cImport
     
    #Region "Constants, Enum and Declarations"
     
        Private Const LOGON32_LOGON_INTERACTIVE As Integer = 2
        Private Const LOGON32_PROVIDER_DEFAULT As Integer = 0
     
     
        'For acces to a folder with a login different of the session
        Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As String, _
                                                            ByVal lpszDomain As String, _
                                                            ByVal lpszPassword As String, _
                                                            ByVal dwLogonType As Integer, _
                                                            ByVal dwLogonProvider As Integer, _
                                                            ByRef phToken As IntPtr) As Integer
     
        'For acces to a folder with a login different of the session
        Declare Auto Function DuplicateToken Lib "advapi32.dll" (ByVal ExistingTokenHandle As IntPtr, _
                                                                 ByVal ImpersonationLevel As Integer, _
                                                                 ByRef DuplicateTokenHandle As IntPtr) As Integer
    #End Region
     
    #Region "Members"
     
        Private _ci As System.Globalization.CultureInfo
        Private _importDir As String
     
    #End Region
     
    #Region "Constructor"
     
        Public Sub New()
     
            Try
     
                'For manipulating excel
                _ci = New System.Globalization.CultureInfo("en-US")
     
            Catch ex As Exception
                MsgBox(ex.Message, MsgBoxStyle.Exclamation)
            End Try
     
        End Sub
     
    #End Region
     
    #Region "Methods"
     
        Private Function DirToArray(ByVal sFolder As String, Optional ByVal sFilter As String = "*.*", Optional ByVal bRecurvise As Boolean = True) As String()
            Try
     
     
                'ajoute le dernier "\"
                If Not (sFolder(sFolder.Length - 1) = "\"c) Then sFolder &= "\"
                'le dossier doit existe
                If Not (System.IO.Directory.Exists(sFolder)) Then Return Nothing
                'récupère le tableau depuis class framework
                If bRecurvise Then
                    Return System.IO.Directory.GetFiles(sFolder, sFilter, IO.SearchOption.AllDirectories)
                Else
                    Return System.IO.Directory.GetFiles(sFolder, sFilter, IO.SearchOption.TopDirectoryOnly)
                End If
            Catch ex As Exception
                DirToArray = {ex.Message}
            End Try
        End Function
     
        Private Function DirToList(ByVal sFolder As String, Optional ByVal sFilter As String = "*.*", Optional ByVal bRecurvise As Boolean = True) As List(Of String)
            'résultat sous forme de collection de chaîne
            Dim ListResult As New List(Of String)
            'récupère le tableau
            Dim asDir() As String = DirToArray(sFolder, sFilter, bRecurvise)
            'intègre dans la liste
            If Not (asDir Is Nothing) Then
                For Each s As String In asDir
                    ListResult.Add(s)
                Next
            End If
            Return ListResult
        End Function
     
        Private Function ImpersonateValidUser(ByRef impersonationContext As WindowsImpersonationContext, _
                                              ByVal userName As String, _
                                              ByVal domain As String, _
                                              ByVal password As String) As Boolean
     
            Dim tempWindowsIdentity As WindowsIdentity
            Dim token As IntPtr
            Dim tokenDuplicate As IntPtr
     
            If LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE, _
                         LOGON32_PROVIDER_DEFAULT, token) <> 0 Then
                If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
                    tempWindowsIdentity = New WindowsIdentity(tokenDuplicate)
                    impersonationContext = tempWindowsIdentity.Impersonate()
                    If impersonationContext Is Nothing Then
                        ImpersonateValidUser = False
                    Else
                        ImpersonateValidUser = True
                    End If
                Else
                    ImpersonateValidUser = False
                End If
            Else
                ImpersonateValidUser = False
            End If
        End Function
     
        ''' <summary>
        ''' Import all data in the quality data
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Import()
     
            'Variable to manipulate files
            Dim impersonationContext As WindowsImpersonationContext = Nothing
            Dim oExcel As Excel.Application = Nothing
     
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
            Try
                If Not ImpersonateValidUser(impersonationContext, "NewLogin", "Domain", "MdP") Then Throw New Exception()
     
                'Open Excel
                oExcel = New Excel.Application
     
                'Begin importations
                ImportNCCAData(oExcel)
     
                undoImpersonation(impersonationContext)
     
            Catch ex As Exception
                MsgBox(ex.Message, MsgBoxStyle.Exclamation)
     
            Finally
                If Not oExcel Is Nothing Then
                    oExcel.Workbooks.GetType().InvokeMember("Close", Reflection.BindingFlags.InvokeMethod, Nothing, oExcel.Workbooks, Nothing, _ci)
                    oExcel.GetType().InvokeMember("Quit", Reflection.BindingFlags.InvokeMethod, Nothing, oExcel, Nothing, _ci)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel)
                    oExcel = Nothing 'freeing memory
                End If
            End Try
     
        End Sub
     
     
        Private Sub ImportNCCAData(ByRef oExcel As Excel.Application)
     
    	Try
     
    'Fonctionne
     Dim importFiles = DirToList("\\MonRepAuquelJeNAiPasAcces", "*.*", True)
                Dim sPluriel = String.Empty
                If (importFiles.Count > 1) Then sPluriel = "s"
                Console.WriteLine(String.Format("{0} fichier{1} trouvé{1}", importFiles.Count, sPluriel))
                For Each s As String In importFiles
                    Console.WriteLine(s)
                Next
     
     
            Dim oSheet = New Excel.Worksheet
     
            Dim sFile As String = _importDir + "\MonFichier.xls"
            Dim sWorkFile As String = _importDir + "\MonFichier_treating.xls"
            If Not File.Exists(sFile) Then Exit Sub
     
     
     
     
                If File.Exists(sWorkFile) Then File.Delete(sWorkFile)
                File.Copy(sFile, sWorkFile)
     
     
    'Plante ici.
                oExcel.Workbooks.GetType().InvokeMember("Open", Reflection.BindingFlags.InvokeMethod, Nothing, oExcel.Workbooks, {sWorkFile, False, True}, _ci)
     
    	'*****
            'Taitement d'importation
    	'*****
     
                'delete the used file
                File.Delete("N:\Divers\Quality_Importation\Rapport NCCA BASE QUALITE_20010808_pending.xls")
     
     
            Catch ex As Exception
                MsgBox(ex.Message, MsgBoxStyle.Critical)
     
            Finally
                If Not oSheet Is Nothing Then oSheet = Nothing
     
                ''Mask progress bar
                'frmMenu.Gauge.Visible = False
                'frmMenu.lblStatus.Visible = False
                'lblProgress.Text = ""
                'pbImportGauge.Value = li_StartRow
     
            End Try
     
        End Sub
     
    #End Region
    Je suis sous windows 7 avec office 2007 et je dois dévelopeer pour un framework3.5.

    Quelqu'un a-t-il une piste pour résoudre ce problème ?

    Edit : Modification du titre pour plus de clarté

  2. #2
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    il est possible de lire un fichier excel comme une base de données
    il faut utiliser system.data.oledb (comme pour access), il y a une chaine de connexion spéciale pour les fichiers excel (voir avec google)
    et ensuite un onglet excel est une table, et la 1ère ligne d'un onglet contient les nom de colonnes, donc faire un SELECT de ce qu'il faut
    (il est meme possible de faire CREATE TABLE pour créer un onglet etc...)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2011
    Messages : 13
    Points : 11
    Points
    11
    Par défaut
    voici

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
     
            Dim xlApp As Excel.Application = New Excel.ApplicationClass
            Dim xlWorkSheet As Excel.Worksheet = New Excel.Worksheet
     
            xlApp.Workbooks.Open(FileName)
            xlWorkSheet = xlApp.Worksheets(Sheet)
     
            SheetName = xlWorkSheet.Name()
     
            If Excel_OK() = 0 Then Exit Sub
            OleDbConnection.Open()
     
          'RngX.Text = A12
          'RngY.Text = D12
     
            OleDbCmd = New System.Data.OleDb.OleDbDataAdapter _
                ("select * from [" & SheetName & "$" & RngX.Text & ":" & RngY.Text & "]", OleDbConnection)
            OleDbCmd.TableMappings.Add("Table", "INFO")
     
            XlDataSet = New System.Data.DataSet
            OleDbCmd.Fill(XlDataSet)
     
            ' libere les lien et vide la datagrid
            DataGridView1.DataSource = Nothing
            DataGridView1.Rows.Clear()
            DataGridView1.Columns.Clear()
     
            DataGridView1.DataSource = XlDataSet.Tables(0)
     
            OleDbConnection.Close()
            releaseObject(OleDbConnection)
            releaseObject(OleDbCmd)
            releaseObject(XlDataSet)
        End Sub
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
        Function Excel_OK()
     
            OleDbConnection = New System.Data.OleDb.OleDbConnection _
               ("provider=Microsoft.Jet.OLEDB.4.0;Data Source='" & FileName & "'; Extended Properties='Excel 8.0;IMEX=1;HDR=No;'")
     
            If ExcelVersion() = "11" Then
                If UCase(Microsoft.VisualBasic.Right(FileName, 3)) <> "XLS" Then
                    MsgBox("File format not supported for this Excel version", MsgBoxStyle.Exclamation, "Excel Version")
                    Return 0
                End If
     
                OleDbConnection = New System.Data.OleDb.OleDbConnection _
                ("provider=Microsoft.Jet.OLEDB.4.0;Data Source='" & FileName & "'; Extended Properties='Excel 8.0;IMEX=1;HDR=No;'")
     
            ElseIf ExcelVersion() = "12" Then
     
                OleDbConnection = New System.Data.OleDb.OleDbConnection _
                ("provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & FileName & "'; Extended Properties='Excel 12.0;IMEX=1;HDR=No;'")
     
            ElseIf ExcelVersion() = "14" Then
                OleDbConnection = New System.Data.OleDb.OleDbConnection _
                ("provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & FileName & "'; Extended Properties='Excel 12.0;IMEX=1;HDR=No;'")
            End If
     
            If OleDbConnection Is Nothing Then
                MsgBox("The Excel version installed on this machine is not supported", MsgBoxStyle.Exclamation, "Excel Version")
                Return 0
            End If
     
            Return 1
        End Function
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
        Private Sub releaseObject(ByVal obj As Object)
            Try
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
                obj = Nothing
            Catch ex As Exception
                obj = Nothing
            Finally
                GC.Collect()
            End Try
        End Sub

  4. #4
    Futur Membre du Club
    Inscrit en
    Février 2011
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 15
    Points : 8
    Points
    8
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
            Dim xlApp As Excel.Application = New Excel.ApplicationClass
            Dim xlWorkSheet As Excel.Worksheet = New Excel.Worksheet
     
            xlApp.Workbooks.Open(FileName)
            xlWorkSheet = xlApp.Worksheets(Sheet)
     
            SheetName = xlWorkSheet.Name()
    Le problème reste le même, l'ouverture du fichier nécessite que l'utilisateur de la session en cours ait accès au fichier (Excel reste indifférent au code d'impersonnalisation). J'ai cependant ignoré ce code pour tester la gestion OleDB car il ne servait (sauf si je me trompe) qu'à avoir le nom de la feuille contenant les données.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
    Dim oOLEDBConnection = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & FileName & "';Extended Properties='Excel 12.0;HDR=YES;IMEX=1;'")
    oOLEDBConnection.Open()
    la création de la connexion OLEDB fonctionne. Son ouverture en revanche me renvoit l'erreur suivante :
    Impossible de démarrer votre application. Le fichier d'informations du groupe de travail est absent ou ouvert en mode exclusif par un autre utilisateur
    Sans le code de substitution de login, cela fonctionne bien.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
          'RngX.Text = A12
          'RngY.Text = D12
     
            OleDbCmd = New System.Data.OleDb.OleDbDataAdapter _
                ("select * from [feuille1$" & RngX.Text & ":" & RngY.Text & "]", OleDbConnection)
    À quoi correspond le A12 et le D12 ? Si c'est une ligne spécifique, comment connaître le numéro de la dernière ligne contenant les données et donc toutes les ramener ? (toujours sans ouvrir excel )

    Merci pour votre aide.

    Je vais regarder un peu plus en détail le fonctionnement de "advapi32.dll" pour voir s'il n'y a pas des paramètres à changer

  5. #5
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    en passant par oledb il n'y a pas de A12 et autres
    il faut que les colonnes aient un titre et après ca fonctionne comme une base de données

    si feuill1 contient les colonnes suivantes nom|prenom|adresse|cp|ville
    tu peux faire select * from feuill1 pour avoir toutes les lignes (ca détecte automatiquement la fin des données)
    tu pourrais aussi faire select nom, prenom from feuill1 where ville = 'paris'
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Futur Membre du Club
    Inscrit en
    Février 2011
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 15
    Points : 8
    Points
    8
    Par défaut
    J'ai dû abdiquer par manque de temps.

    Je n'utilise plus d'impersonalisation (après de multiple tests, quel que soit le type de logon et de type de token ça bloque toujours au niveau d'ouverture de connexion oledb)

    L'utilitaire sera donc lancé soit :

    - par un utilisateur ayant les droits d'accès nécessaires aux différents répertoires (dans le cadre d'une utilisation ponctuelle)

    - avec une tâche planifiée utilisant le login et le mot de passe d'un utilisateur ayant les accès nécessaires (créé spécialement pour ça).

    Passer par l'OleDB m'évite d'avoir une licence Excel sur le poste accueillant l'utilitaire et je dois même gagner en rapidité .

Discussions similaires

  1. [POI] Importer fichier Excel avec plusieurs feuilles
    Par ninoch07 dans le forum Documents
    Réponses: 9
    Dernier message: 10/02/2015, 09h59
  2. [ODS] Import Fichier Excel avec cellules fusionnées
    Par Keddy dans le forum ODS et reporting
    Réponses: 2
    Dernier message: 24/10/2014, 21h37
  3. Importer fichier excel avec PDI
    Par marc73450 dans le forum Pentaho
    Réponses: 0
    Dernier message: 27/09/2013, 15h07
  4. [SSIS] [2K5] Import fichier excel avec SSIS
    Par alaabed dans le forum SSIS
    Réponses: 4
    Dernier message: 28/01/2010, 18h00
  5. Importer un fichier EXcel avec option "parcourir"
    Par marie10 dans le forum Access
    Réponses: 1
    Dernier message: 01/02/2006, 10h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo