WinFuture-Forum.de: Batch Excel Zeilenweise auslesen - WinFuture-Forum.de

Zum Inhalt wechseln

Nachrichten zum Thema: Entwicklung
  • 2 Seiten +
  • 1
  • 2

Batch Excel Zeilenweise auslesen Batch Excel Zeilenweise auslesen


#1 Mitglied ist offline   Domo991 

  • Gruppe: Mitglieder
  • Beiträge: 7
  • Beigetreten: 09. Oktober 14
  • Reputation: 0

geschrieben 09. Oktober 2014 - 14:10

Hallo Zusammen (bin neu hier),

ich habe ein Problem und fände es schön wenn mir jemand helfen könnte.

Problemdarstellung:

Ich möchte, dass mein Skript (Batch) die Zeilen aus einer Excel Tabelle nacheinander einliest.

Ablauf:
Das Skript beginnt und nimmt aus der ersten Spalte Zeile 1 den ersten Text.
Dann läuft das Skript einmal durch und fängt oben erneut an.
Dann nimmt das Skript aus der Spalte 1 den Text aus der zweiten Zeile. (usw.)
Das geht solange bis die Excel Datei keine Einträge mehr enthält.

Mein aktueller Code sieht so aus:

@echo off

for /f "tokens=* delims=;" %%a in (Datenbank.csv) do set "SERVERIP=%%a"
set PORT=22

start telnet.exe %SERVERIP% %Port%
ping %SERVERIP%

set pid=
for /f "tokens=2" %%i in ('tasklist^|findstr /b "telnet.exe"') do set "PID=%%i"
echo %PID% > pid.txt

if "%pid%"=="" (

echo Port %Port% ist zu
echo Port %Port% ist zu>>log.txt

goto :EOF)

@taskkill /PID %pid% >nul

echo Port %Port% ist offen
echo Port %Port% ist offen>>log.txt

:EOF

:ENDE

-------------

Das Skript schreibt mir in eine Tabelle ob bestimmte Ports bestimmter DNS Namen erreichbar sind.
Hat den Hintergrund, dass wir über den Port feststellen wollen, ob die jeweiligen clients erreichbar sind.

Nachher will ich die Ergebnisse in einer Excel Tabelle grafisch darstellen. Aber nun erstmal das....

Kann mir hier jemand helfen?

Vielen Dank im Voraus

Lieben Gruß

Domenik

Dieser Beitrag wurde von Domo991 bearbeitet: 09. Oktober 2014 - 14:15

0

Anzeige



#2 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.902
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 09. Oktober 2014 - 15:47

Was steht denn in der CSV so drin? :unsure: Wenn ich das richtig verstehe, findet sich in der ersten Spalte die Server-IP. Die übrigen Spalten... werden die nicht gebraucht? Oder doch?

Ich frag mich auch grad, was der Ping-Befehl da tun soll. Ausgewertet wird da ja nichts. :unsure:

Port 22/tcp ist doch eigentlich SSH. Wär es da nicht sinnvoller, irgendein SSH-kompatibles (Kommandozeilen-)Tool zu verwenden, welches eine Verbindung aufbaut und dann nach einem vordefinierten (möglichst kurzen) Timeout automatisch aussteigt? Dann müßtest Du nur noch den ERRORLEVEL überprüfen, den das fragliche Tool dann hoffentlich in Abhängigkeit des Verbindungs-Erfolgs zurückgibt.

Genaugenommen muß dieses Tool ja nichts weiter leisten als eben das, sodaß man sich -notfalls mit ein bißchen Einarbeiten- was schnelles-und-unsauberes in der Programmiersprache der Wahl selber zusammenbasteln könnte.

Das würde den Vorgang sehr stark vereinfachen. Besonders, wenn das nicht nur 100 Zeilen sind, die da behandelt werden sollen.


... Ansonsten ist mir im Augenblick grad nicht ganz klar, woran es genau "hakt" - was funktioniert denn nicht so, wie Du's gerne gehabt hättest?

Dieser Beitrag wurde von RalphS bearbeitet: 09. Oktober 2014 - 15:50

"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
0

#3 Mitglied ist offline   Stefan_der_held 

  • Gruppe: Offizieller Support
  • Beiträge: 14.346
  • Beigetreten: 08. April 06
  • Reputation: 890
  • Geschlecht:Männlich
  • Wohnort:Dortmund NRW
  • Interessen:Alles wo irgendwie Strom durchfließt fasziniert mich einfach weswegen ich halt Elektroinstallateur geworden bin :)

geschrieben 09. Oktober 2014 - 15:52

Das Thema was ua. vorhanden sein wird ist das

|


als Trennzeichen... Dies ist in Batch eigentlich ein Verkettungsoperator.

d.h. man müsste verhindern, dass die Batch dies als Operator sieht.
0

#4 Mitglied ist offline   Domo991 

  • Gruppe: Mitglieder
  • Beiträge: 7
  • Beigetreten: 09. Oktober 14
  • Reputation: 0

geschrieben 09. Oktober 2014 - 15:58

Hallo vielen Dank für deine Antwort,

Vorab, ich bin kein Programmierer... und deswegen ist das was ich da habe schon (wahrscheinlich mies) zusammengewürfelt.
Wie du richtig erkannt hast stehen in der csv Datei die IP Adressen in Spalte 1 untereinander.

Der Pingbefehl simmuliert nur eine Wartezeit damit etwas zeit vergeht bis die Verbindung erfolgreich abgeschlossen oder bereits beendet wurde, weil keine Verbindung aufgebaut werden konnte.
Ich prüfe eigentlich nur ob die telnet.exe noch aktiv ist (bedeutet also dass der Port erreichbar ist) oder die Verbindung garnicht aufgebaut werden konnte und die telnet.exe bereits geschlossen wurde (bedeutet port nicht erreichbar - Client nicht erreichbar).

Das Programm funktioniert soweit auch, jedoch weiß ich nicht wie ich das Skript dazu bekomme, dass wenn es mit der ersten Port Überprüfung fertig ist, er automatisch das Skript erneut startet und aus der Tabelle die zweite Ip auf den Port prüft. Er Soll hat alle Ip Adressen prüfen die in der Excel Tabelle stehen.

Das muss ja irgendwie mit einer while schleife gehen?
0

#5 Mitglied ist offline   mephistolino 

  • Gruppe: aktive Mitglieder
  • Beiträge: 469
  • Beigetreten: 17. September 10
  • Reputation: 36
  • Geschlecht:unbekannt

geschrieben 09. Oktober 2014 - 16:25

auch, wenn du sagst, dass du kein programmierer bist (was du auch nicht sein musst): wäre es mit vba nicht einfacher, wo du dich schon in einer excel-tabelle bewegst?
0

#6 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.902
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 09. Oktober 2014 - 17:31

Aah. :imao: Ich seh, wo das Problem ist.

Du mußt in Batch den Schleifenkörper mit ( ) einschließen. Sonst geht es nicht.

Also so:
for ... in (...) do @(
REM BEFEHLE
REM NOCH MEHR BEFEHLE
)



Mit for wird immer nur das "geschleift", was unmittelbar dahinter steht. Das wäre in diesem Fall der durch ( ) umschlossene Block. Deswegen MUß die ( auch auf dieselbe Zeile wie das "for" selber.


Dann sollte es eigentlich auch schon gehen.
"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
0

#7 Mitglied ist offline   Domo991 

  • Gruppe: Mitglieder
  • Beiträge: 7
  • Beigetreten: 09. Oktober 14
  • Reputation: 0

geschrieben 10. Oktober 2014 - 10:18

Hallo vielen Dank schonmal für die Antworten =)

Ich hab das mit der Schleife leider noch nicht verstanden. Könntest du mir anhand meines Skriptes zeigen wo die Klammern hin müssen?

Gruß
0

#8 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.902
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 13. Oktober 2014 - 09:13

Die Klammern müssen um das rum, was halt mehrfach ausgeführt werden soll. :wink:

Ohne das jetzt groß getestet zu haben:

@echo off

for /f "tokens=* delims=;" %%a in (Datenbank.csv) do @(
 set PORT=22
 start telnet.exe %%a %Port%
 timeout /t 5
 for /f "tokens=2" %%i in ('tasklist /fi  "IMAGENAME eq telnet.exe" /nh') do @(
  echo "PID=%%i" > pid.txt

  if "%%i"=="" (
  echo Port %Port% auf Server %%a ist zu
  echo Port %Port% auf Server %%a ist zu>>log.txt
  goto :EOF
 ) else (
 echo Port %Port% auf Server %%a ist offen
 echo Port %Port% auf Server %%a ist offen>>log.txt
 taskkill /PID %%i >nul
 )
)
:EOF

:ENDE


- Die Verkettung ist aus dem for()-Kopf rausgeflogen
- "ping" mit "timeout" ersetzt
- Ich hab das 'echo PID=...' in pid.txt dringelassen, auch wenn es keinen echten Sinn ergibt (die PID wird bei jedem Durchlauf überschrieben und selbst wenn man das mit '>>' statt des '>' umgeht, wird der jeweilige Prozeß sowieso umgehend beendet.
- Durchaus möglich, daß da noch irgendwo Syntaxfehler drinstecken.

Dieser Beitrag wurde von RalphS bearbeitet: 13. Oktober 2014 - 12:07

"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
0

#9 Mitglied ist offline   Decay 

  • Gruppe: aktive Mitglieder
  • Beiträge: 884
  • Beigetreten: 09. Juni 04
  • Reputation: 7
  • Geschlecht:Männlich

geschrieben 16. Oktober 2014 - 16:59

Hmmmm, finde es über eine batch-Datei recht umständlich, dies zu realisieren.

Ein guter Ansatz zu einem vb.net Programm zum Beispiel wäre sowas hier:
Public startPort As Integer
Public endPort As Integer
Public IPAddress As String

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

        Try
            Dim lvi As New ListViewItem(startPort)
            Dim tryToConnect As System.Net.Sockets.TcpClient = New System.Net.Sockets.TcpClient(IPAddress, startPort)

            'Es kann eine Verbindung hergestellt werden
            'somit ist der Port offen
            lvi.SubItems.Add("is opend")
            lvi.ForeColor = Color.Red
            lvi.EnsureVisible()
            BackgroundWorker1.ReportProgress(0, lvi)

        Catch ex As Exception
            'Es kann keine Verbindung hergestellt werden
            'somit ist der Port geschlossen
            Dim lvi As New ListViewItem(startPort)
            lvi.SubItems.Add("is Closed")
            lvi.SubItems.Add(ex.Message)
            lvi.ForeColor = Color.Green
         
            BackgroundWorker1.ReportProgress(0, lvi)

        End Try
End Sub


Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        Dim lvi As New ListViewItem

        'Daten vom Backgroundworker holen
        lvi = e.UserState

        Me.ListView1.Items.Add(lvi)
        'Das akteulle ListviewItem anzeigen
        lvi.EnsureVisible()

End Sub



Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        BackgroundWorker1.WorkerReportsProgress = True
        BackgroundWorker1.WorkerSupportsCancellation = True

        IPAddress = "10.0.0.1"
        startPort = 100
        endPort = 110

        For startPort = startPort To endPort
            Me.BackgroundWorker1.RunWorkerAsync()

            'Da ein Backgroundworker immer nur eine
            'Aufgabe ausführen kann, warten wir hier
            'bis er fertig ist und mit der nächsten
            'Aufgabe weitermachen kann
            While Me.BackgroundWorker1.IsBusy = True
                Application.DoEvents()
            End While
        Next

End Sub



Noch etwas modifiziert und du kannst über eine Textbox direkt die IP oder Hostname vom Rechner/Server eingeben, der gescannt werden soll.
Oder du kannst es zusätzlich in einer Datei schreiben lassen.
Oder du definierst die Server direkt in einer Drop-Down-Box vor, sodass du nur noch den Server/Rechner auswählen brauchst.

Was du definitv dazu brauchst, ist:
Eine Windows-Form
Ein Button
Ein Backgroundworker

Vllt wäre das eher etwas, was euch ansprechen tät.... zumal es doch etwas komfortabler ist *find* :unsure:

Dieser Beitrag wurde von Decay bearbeitet: 17. Oktober 2014 - 12:04

1

#10 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.902
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 16. Oktober 2014 - 19:45

Wäre zumindest angenehmer (und vor allem schneller) als in Batch, weil man das da parallel abarbeiten lassen kann. :) Idealerweise natürlich mit einem gewissen Limit, damit nicht potentiell Hunderttausende Anfragen auf einmal rausgehen. :o

Dieses "eins nach dem andern" stößt mir bei Batch aber doch ein bissel sauer auf. Das wird ja sonst bei vielen Servern "nie" fertig. Aber so "richtig" parallel geht es eben auch nicht.

Hatte das ja erst mit start /W angedacht,aber dann geht das Script ja gar nicht erst weiter, das ist also auch keine echte Option. Man müßte in Batch mehr oder weniger für jeden Server einen Telnetprozeß starten (foreach Server in Liste do start telnet $Server) und für jeden Prozeß die PID sichern; wenn das passiert ist, noch ein, zwei Momente abwarten (Verbindungstimeouts abfangen) und dann die (notierte) PID-Liste durchgehen, welche Prozesse davon aktiv sind (Verbindung gut) oder nicht (Verbindung schlecht). Zumindest dann, wenn es halbwegs schnell gehen soll.

Problem ist nur, das frißt Resourcen und ist unzuverlässig - irgendwann kriegt Windows keine neuen (zusätzlichen) Verbindungen mehr auf und damit ist das Script an dieser Stelle unbrauchbar geworden - ganz abgesehen davon natürlich, daß dann (maximal) "Anzahl Server" viele Telnetprozesse aktiv sind und zumindest potentiell das System lahmlegen.

Damit das nicht passiert, und diesen Ansatz hab ich versucht zu verfolgen, bliebe nur, einen Server nach dem anderen durchzugehen und a) Verbindung auf; b) Warten; c) Check, ob Verbindung noch besteht - hier müßte man ggf auch nach Alternativen Telnetclients schauen, die auch ERRORLEVELs zurückgeben --- und d) das entsprechend auswerten. C dauert da potentiell am längsten - ich krieg grad ca. 2 Sekunden/Fehlschlag Wartezeit, die man also zumindest pro Eintrag abwarten müßte - drei wäre also das ABSOLUTE Minimum an einzuplanender Wartezeit und damit haben wir (bestenfalls) 20 Server pro Minute, die wir da abarbeiten können, oder etwa 100 Server in fünf Minuten (plus oder minus ein paar). Dazu kommen aber noch die ganzen anderen Checks und Routinen, sodaß das durchaus auch fünf oder mehr Sekunden pro Servercheck werden können... und dann sind es plötzlich nur noch ca. 10/min bzw. knappe zehn Minuten pro 100 Server.

Denke, das ist nicht praktikabel.
"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
0

#11 Mitglied ist offline   Domo991 

  • Gruppe: Mitglieder
  • Beiträge: 7
  • Beigetreten: 09. Oktober 14
  • Reputation: 0

geschrieben 23. Oktober 2014 - 09:32

Hallo Zusammen, ich habe es nun geschafft den Quellcode in VB einzubinden und die Steuerelemente eingebunden.
Ich schaffe es aber nicht nun die IPAdresse aus der Excel Datei zu lesen. Könnte mir da vielleicht jemand einen Hinweis geben?

Liebe Grüße
Domenik
0

#12 Mitglied ist offline   Decay 

  • Gruppe: aktive Mitglieder
  • Beiträge: 884
  • Beigetreten: 09. Juni 04
  • Reputation: 7
  • Geschlecht:Männlich

geschrieben 23. Oktober 2014 - 10:23

Beitrag anzeigenZitat (Domo991: 23. Oktober 2014 - 09:32)

Hallo Zusammen, ich habe es nun geschafft den Quellcode in VB einzubinden und die Steuerelemente eingebunden.
Ich schaffe es aber nicht nun die IPAdresse aus der Excel Datei zu lesen. Könnte mir da vielleicht jemand einen Hinweis geben?

Liebe Grüße
Domenik


Ist die Excel Datei dynamisch, also verändert sie sich jedesmal? Sind es viele IPs?
Ansonsten empfehle ich die IPs in einer Text-Datei zu kopieren und diese dann einzulesen.
Mit einer For each-Schleife kannst du dann jede Zeile z.B. in einer Drop-Down Box ablegen und ab dort dann weiter arbeiten.
0

#13 Mitglied ist offline   Domo991 

  • Gruppe: Mitglieder
  • Beiträge: 7
  • Beigetreten: 09. Oktober 14
  • Reputation: 0

geschrieben 23. Oktober 2014 - 15:51

Also... Es sind um die 900 IP Adressen mit jeweils 3 Ports. Das Programm soll quasi beim ausführen alle IP Adressen + Port prüfen und die IP Adressen mit Ports die nicht erreicht wurden in eine Excel Liste oder o.ä. schreiben. (Das soll am Ende rauskommen.)
0

#14 Mitglied ist offline   Decay 

  • Gruppe: aktive Mitglieder
  • Beiträge: 884
  • Beigetreten: 09. Juni 04
  • Reputation: 7
  • Geschlecht:Männlich

geschrieben 23. Oktober 2014 - 16:34

Es geht erstmal darum, die 900 IPs einzulesen.... da erwähntest du eine excel-Tabelle. Hmmmm, ich frage mich, sofern ein AD besteht, ob es nicht besser ist per DNS alle derzeit angemeldeten Rechner zu bestimmen und diese auf die Ports zu überprüfen.
Damit fällt die Excel Tabelle weg und ein ausgeschalteter Computer kann sowieso nicht gescant werden.

Dazu müssen aber mehr Infos kommen :-)
0

#15 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.902
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 24. Oktober 2014 - 16:13

Habe hier ne kleine Mini-Implementierung zusammengebastelt. Diese allerdings in PowerShell, und besonders flink ist sie auch nicht (in Abhängigkeit davon, wieviele der vorhandenen Hosts nicht antworten).

Könnte man sicherlich auch noch in einzelne Jobs aufteilen (nach Divide + Conquer Prinzip), je nach Anzahl der vorhandenen Kerne (und Systemressourcen - aber nicht geprüft, wie hungrig das wird). Dann geht es entsprechend schneller.

"Optimal" wäre natürlich was über Broad- oder Multicast, wenn die einzelnen Rechner nicht von sich aus "Hallo Welt" sagen können, oder dürfen. Das wird aufwendiger, geht dann aber ratzfatz.
"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
0

Thema verteilen:


  • 2 Seiten +
  • 1
  • 2

1 Besucher lesen dieses Thema
Mitglieder: 0, Gäste: 1, unsichtbare Mitglieder: 0