Announcement

Collapse
No announcement yet.

Daten von SQL-Server nach Excel/Access exportieren

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Daten von SQL-Server nach Excel/Access exportieren

    Hallo

    Ich verwende MS SQL-Server 7.0 und ADO. Nun muss ich die Daten (zB. von einem DBGrid) über den Provider <B>'SQLOLEDB'</B> als XLS- und MDB-Datei exportieren.
    Die Anweisung <B>'SELECT * INTO %2 IN "C:\Temp\%s" "Excel 8.0;" FROM Art'</B> zusammen mit dem Provider 'Microsoft.Jet.OLEDB.4.0' funktioniert zwar einwandfrei. Mit 'SQLOLEDB' kommt jedoch die Fehlermeldung <B>'Falsche Syntax in der Nähe von "IN"</B>.
    Ich brauche dringend eine Lösung. Wer kann mir helfen?

  • #2
    Hallo,
    Hallo,

    Aus einer MDB-File eine CSV-File machen und zwar über ADO ,wie geht das ? #1 - Andreas Kosch 14.09.2001 7:33
    Hallo,
    das folgende Beispiel demonstriert, wie man mit Hilfe der Jet Engine eine Tabelle (Bsp: Customer) aus einer ACCESS-Datenbank in die verschiedenen Formate exportieren kann:


    <pre>
    procedure TForm1.ButtonExportClick(Sender: TObject);
    resourcestring
    cSQL1 = 'SELECT * INTO [Export.%s] IN "C:\Temp" "%s;" FROM Customer';
    cSQL2 = 'SELECT * INTO %s IN "C:\Temp\%s" "Excel 8.0;" FROM Customer';
    cSQL3 = 'SELECT * INTO [%s] IN "C:\Temp\%s" FROM Customer';
    var
    sSQL : String;
    iRows: Integer;
    begin
    case RadioGroupExport.ItemIndex of
    0 : sSQL := Format(cSQL1, ['dbf', 'dBASE 5.0']);
    1 : sSQL := Format(cSQL1, ['db', 'Paradox 5.x']);
    2 : sSQL := Format(cSQL1, ['htm', 'HTML Export']);
    3 : sSQL := Format(cSQL1, ['txt', 'Text']);
    4 : sSQL := Format(cSQL2, ['Tabelle1', 'Export.xls']);
    5 : sSQL := Format(cSQL3, ['Cust', 'Test1.MDB']);
    end;
    ADOConnection1.Connected := True;
    ADOConnection1.Execute(sSQL, iRows);
    ADOConnection1.Connected := False;
    ShowMessage(Format('Es wurden %d Datensätze exportiert.', [iRows]));
    end;
    </pre>

    Gruß Mathias
    &#10

    Comment


    • #3
      Hallo

      Danke für die rasche Antwort. Leider funktioniert ja diese Lösung nicht mit dem <B>SQLOLEDB</B>-Provider, wie bereits Eingangs erwähnt. <BR>Ich brauche den Export unbedingt direkt vom SQL-Server, und nicht über Access

      Comment


      • #4
        Hallo,

        wenn der MS SQL Server auf eine bestimmte fremde Datenmenge nicht über OPENROWSET direkt zugreifen kann, steht immer noch der Weg des direkten Kopierens über 2 Recordset-Objekte zur Verfügung. Das folgende Beispiel demonstriert, wie die Datensätze aus einer MS SQL Server 2000-Tabelle in eine Excel-Tabelle kopiert werden. Da nur der OLE DB Provider der Microsoft Jet Engine die fremden Datenbankformate (XLS, DB, XML, CSV, HTML etc.) schreiben kann, ist der "Umweg" über ein zweites Recordset notwendig:
        <pre>
        uses ADOInt;

        procedure TForm1.ButtonExportClick(Sender: TObject);
        resourcestring
        cCSMSSQL = 'Provider=SQLOLEDB.1;Integrated Security=SSPI;' +
        'Persist Security Info=False;' +
        'Initial Catalog=Northwind;Data Source=(local)';
        cCSJET = 'Provider=Microsoft.Jet.OLEDB.4.0;' +
        'Data Source=C:\TEMP\MSSQLExport.xls;' +
        'Extended Properties=Excel 8.0;' +
        'Persist Security Info=False';
        var
        aConMSSQL : _Connection;
        aConJET : _Connection;
        aRSMSSQL : _Recordset;
        aRSJet : _Recordset;
        begin
        // Schritt 1: Daten von MS SQL laden (ReadOnly)
        aConMSSQL := CoConnection.Create;
        aConMSSQL.CursorLocation := adUseClient;
        aConMSSQL.Open(cCSMSSQL, '', '', adConnectUnspecified);
        try
        aRSMSSQL := CoRecordSet.Create;
        aRSMSSQL.Set_ActiveConnection(aConMSSQL);
        aRSMSSQL.CursorLocation := adUseClient;
        try
        aRSMSSQL.Open('SELECT * FROM dbo.Region', EmptyParam,
        adOpenStatic, adLockReadOnly, adCmdText);
        aConJET := CoConnection.Create;
        aConJET.CursorLocation := adUseClient;
        aConJET.Open(cCSJET, '', '', adConnectUnspecified);
        try
        aRSJet := CoRecordSet.Create;
        aRSJet.Set_ActiveConnection(aConJET);
        aRSJet.Open('Daten', EmptyParam, adOpenStatic,
        adLockOptimistic, adCmdTableDirect);
        aRSMSSQL.MoveFirst;
        // Schritt 2: Daten in die XLS-Tabelle schreiben
        while not aRSMSSQL.EOF do
        begin
        aRSJet.AddNew(EmptyParam, EmptyParam);
        aRSJet.Fields[0].Value := aRSMSSQL.Fields[0].Value;
        aRSJet.Fields[1].Value := aRSMSSQL.Fields[1].Value;
        aRSJet.Update(EmptyParam, EmptyParam);
        aRSMSSQL.MoveNext;
        end;
        aRSJet.Close;
        aRSJet := nil;
        finally
        aConJET.Close;
        aConJET := nil;
        end;
        aRSMSSQL.Close;
        finally
        aRSMSSQL := nil;
        end;
        finally
        aConMSSQL.Close;
        aConMSSQL := nil;
        end;
        end;
        </pre&gt

        Comment


        • #5
          Hallo Herr Kosch,

          ...nun wird es aber interessant. Ich habe Ihr Beispiel natürlich sofort ausprobiert und erhalte in diesem Satz <I>aRSJet.Open('Daten', EmptyParam, adOpenStatic, adLockOptimistic, adCmdTableDirect);</I> noch folgende Fehlermeldung:<BR>
          <I>Das Microsoft Jet-Datenbankmodul konnte das Objekt 'Daten' nicht finden. Stellen Sie sicher, dass das Objekt existiert und dass die Namens- und Pfadangaben richtig eingegeben wurden.</I><BR>

          Woran liegt das? Was mache ich falsch

          Comment


          • #6
            Hallo,

            die Antwort auf diese Frage hängt davon ab, welche Excel-Version auf dem Rechner installiert ist. Bei Excel XP reicht es aus, den Namen des Worksheets zu übergeben, wobei dem Namen ein $-Zeichen angehängt wird. Bei Excel 2000 ist es notwendig, über <i>Einfügen | Name | Definieren</i> einen Namen (wie "Daten") für den Bereich der "Datenbank-Tabelle" im ExcelSheet zu geben.

            Will man diese Namensvergabe umgehen, kann man den Inhalt der Daten auch direkt über Automation eintragen lassen. Das <b>Range</b>-Objekt von Excel stellt dazu die Methode <b>CopyFromRecordset</b> zur Verfügung, so dass die Datensätze der MS SQL Server-Abfrage ohne "Umweg" des 2. Recordsets direkt in der XLS-Datei eingetragen werden können:
            <pre>
            procedure TForm1.ButtonInsertClick(Sender: TObject);
            var
            aRS : _RecordSet;
            iCnt : Integer;
            i : Integer;
            aRange : Range;
            aField : Field;
            begin
            aRS := ADOTable1.Recordset;
            iCnt := aRS.Fields.Count;
            // Spaltenbeschriftung
            for i := 1 to iCnt do
            begin
            aRange := IDispatch(ExcelWorksheet1.Cells.Item[9,i]) as Range;
            with aRange do
            begin
            Font.Bold := True;
            aField := aRS.Fields[i-1];
            Value := aField.Name;
            EntireColumn.ColumnWidth := aField.ActualSize;
            end;
            end;
            // Daten aus der ADO-Datenmenge kopieren
            ExcelWorksheet1.Range['A10','A10'].CopyFromRecordset(aRS, EmptyParam, EmptyParam);
            end;
            </pre&gt

            Comment


            • #7
              Hallo Herr Kosch

              Vielen Dank für Ihre Bemühungen. Leider bekomme ich immer noch eine Fehlermeldung <I>Schnittstelle nicht unterstützt</I> in folgender Zeile aus Ihrem 2.Beispiel<BR>
              <I>aRange := IDispatch(ExcelWorksheet1.Cells.Item[9,i]) as Range;</I><BR>
              <BR>
              Ich verwende hauptsächlich Excel97, habe aber auch mit Excel2000 probiert. Die Komponenten sollten im Delphi eigentlich auch richtig installiert sein.<BR>
              Wenn ich in der "Datenbank-Tabelle" im ExcelSheet den Eintrag (zB. 'Daten') von Hand vornehme (wie oben beschrieben), werden die Daten problemlos exportiert. Aber diesen manuellen Eingriff muss ich unbedingt umgehen können.<BR>
              <BR>
              Wo kann das Problem noch liegen

              Comment


              • #8
                Hallo,

                das CopyFromRecordset-Beispielprogramm stammt aus meinem Buch <i>COM/DCOM/COM+ mit Delphi</i> (Verzeichnis »Kapitel 12\Office2000\Excel2000« auf der CDROM) und sollte mit Excel 2000 in jedem Fall funktionieren (wenn das Programm auch Excel2000.pas einbindet).

                Die Zeile mit der Typumwandlung ist nicht notwendig, da hier nur die kosmetische Beschriftung erfolgt. Die Übernahme der Daten findet nur in der letzten Zeile statt.

                &gt;Aber diesen manuellen Eingriff muss ich unbedingt umgehen können.

                Wenn Excel installiert ist, kann man diesen Namen auch über die Fernbedienung von Excel über Automation direkt aus dem eigenen Programm heraus vergeben

                Comment

                Working...
                X