mit folgender Anweisung...
*****
[snip]
On Error Resume Next
Workbooks.Open Filename:= _
"C:\DATEN\Zusammenfassung.xls"
Workbooks("Zusammenfassung").Activate
Sheets("Alle").Activate
Range("A65536").End(xlUp).Select
ActiveCell.Offset(1, 0).Select
ActiveSheet.Paste
End Sub
*****
....werden Daten, die zuvor markiert wurden, in die
Datei "Zusammenfassung" kopiert. Wenn die
Datei "Zusammenfassung" geöffnet bleibt und ich weitere
Daten hinzufügen will, so erhalte ich die Meldung, "Die
Datei ist bereits geöffnet. Wollen Sie sie erneut öffnen?
Alle bislang eingegebenen Änderungen gehen damit verloren".
Wie muß der Code geändert werden, damit a) die Datei
geöffnet wird (wenn noch nicht offen) und b) die Daten
auch in eine bereits geöffnete Datei kopiert werden?
Vielen Dank schon einmal im Voraus.
cu
Götz
-----
Excel 2000
Götz Alles schrieb am 22.06.2004
> On Error Resume Next
> Workbooks.Open Filename:= _
> "C:\DATEN\Zusammenfassung.xls"
>
> Workbooks("Zusammenfassung").Activate
> Sheets("Alle").Activate
>
> Range("A65536").End(xlUp).Select
> ActiveCell.Offset(1, 0).Select
> ActiveSheet.Paste
>
> End Sub
> *****
> ....werden Daten, die zuvor markiert wurden, in die
> Datei "Zusammenfassung" kopiert. Wenn die
> Datei "Zusammenfassung" geöffnet bleibt und ich weitere
> Daten hinzufügen will, so erhalte ich die Meldung, "Die
> Datei ist bereits geöffnet. Wollen Sie sie erneut öffnen?
> Alle bislang eingegebenen Änderungen gehen damit verloren".
>
> Wie muß der Code geändert werden, damit a) die Datei
> geöffnet wird (wenn noch nicht offen) und b) die Daten
> auch in eine bereits geöffnete Datei kopiert werden?
Prüfe im Vorfeld, ob die Mappe schon geöffnet ist (war das nicht eine
Frage, die Du schon gestellt hast?).
Die folgende Funkton liefert 'TRUE', wenn die Mappe shcon geöffnet ist:
Public Function WorkbookIsOpen(strName As String) As Boolean
Dim wbWorkbook As Workbook
On Error Resume Next
Set wbWorkbook = Workbooks(strName)
WorkbookIsOpen = IIf(wbWorkbook Is Nothing, False, True)
End Function
In deinen Coe eingebaut könntest Du dies wie folgt nutzen:
*****
If Not WorkbookIsOpen("Zusammenfassung") then
Workbooks.Open Filename:= _
"C:\DATEN\Zusammenfassung.xls"
End If
Workbooks("Zusammenfassung").Activate
Sheets("Alle").Activate
Range("A65536").End(xlUp).Select
ActiveCell.Offset(1, 0).Select
ActiveSheet.Paste
End Sub
--
Mit freundlichen Grüssen
Thomas Ramel
- MVP für Microsoft-Excel -
[Win XP Pro SP-1 / xl2000 SP-3]
>Prüfe im Vorfeld, ob die Mappe schon geöffnet ist (war
>das nicht eine Frage, die Du schon gestellt hast?).
Ja, richtig. Aber wenn ich nicht mit Blindheit geschlagen
bin, dann wurde die Frage noch nicht beantwortet. Sorry,
dass ich dort nciht nochmal nachgefragt habe. Ich dachte,
die Frage sei untergegangen.
>Die folgende Funkton liefert 'TRUE', wenn die Mappe schon
>geöffnet ist:
[snip]
>In deinen Code eingebaut könntest Du dies wie folgt
>nutzen:
[snip]
Durch "On Error Resume Next" fange ich einen Fehler ab,
der wohl in der "Workbooks("Zusammenfassung").Activate"
Anweisugn steckt.
Wenn die Datei "Zusammenfassung" geschlossen ist, dann
läuft alles wunderbar. Ist sie offen, dann wird sie (mit
obigem Code) nicht aktiviert. Die zu kopierenden Daten
weden dann auf den Ursprungsblatt eingefügt!?!
Was ist denn an der Anweisung "Workbooks
("Zusammenfassung").Activate" falsch?
Vielen Dank aber schon einmal für Deine Hilfe!
cu
Götz
Götz Alles schrieb am 22.06.2004
>>Prüfe im Vorfeld, ob die Mappe schon geöffnet ist (war
>>das nicht eine Frage, die Du schon gestellt hast?).
>
> Ja, richtig. Aber wenn ich nicht mit Blindheit geschlagen
> bin, dann wurde die Frage noch nicht beantwortet. Sorry,
> dass ich dort nciht nochmal nachgefragt habe. Ich dachte,
> die Frage sei untergegangen.
Das ist wieter kein Problem - ich habe mich nur daran erinnert und wollte
das Ganze gleich 'in einem Aufwasch' abhandeln und mich daher vergewissern.
> Durch "On Error Resume Next" fange ich einen Fehler ab,
> der wohl in der "Workbooks("Zusammenfassung").Activate"
> Anweisugn steckt.
>
> Wenn die Datei "Zusammenfassung" geschlossen ist, dann
> läuft alles wunderbar. Ist sie offen, dann wird sie (mit
> obigem Code) nicht aktiviert. Die zu kopierenden Daten
> weden dann auf den Ursprungsblatt eingefügt!?!
>
> Was ist denn an der Anweisung "Workbooks
> ("Zusammenfassung").Activate" falsch?
Hmmm, weshalb aktivierst und selektierst Du die Zelle?
Lass dir die folgende Anweisung 'auf der Zunge zergehen' - sie sollte das
Ganze gleich direkt machen.
Wenn du sie als Parameter an die Copy-Anweisung hängst, ist auch die
.Paste-Operation hinfällig, sofern die Mappe zuvor offen ist:
If Not WorkbookIsOpen("Zusammenfassung") Then
Workbooks.Open Filename:= _
"C:\DATEN\Zusammenfassung.xls"
End If
Workbooks("Zusammenfassung").Sheets("Alle"). _
Range("A65536").End(xlUp).Offset(1, 0).Paste
Das klingt super, aber leider haut es mit dem Einfügen
nicht hin. Weder bei geschlossener noch
geöffneter "Zusammenfassen" Datei werden die Daten
eingefügt. Wenn die Datei geschlossen ist, wird diese aber
geöffnet und die richtige Zelle (A3) wird selektiert. Wenn
ich dann unter <Bearbeiten> schaue, dann ist die Einfügen-
Option verfügbar. Klicke ich drauf, werden die zuvor
korrekt selektierten Daten aus der anderen Datei
eingefügt!?!?
Ich verstehe überhaupt nicht, woran das liegen könnte.
cu
Götz
Götz Alles schrieb am 22.06.2004
>>If Not WorkbookIsOpen("Zusammenfassung") Then
>>Workbooks.Open Filename:= _
>> "C:\DATEN\Zusammenfassung.xls"
>>End If
>>
>>Workbooks("Zusammenfassung").Sheets("Alle"). _
>>Range("A65536").End(xlUp).Offset(1, 0).Paste
>
> Das klingt super, aber leider haut es mit dem Einfügen
> nicht hin. Weder bei geschlossener noch
> geöffneter "Zusammenfassen" Datei werden die Daten
> eingefügt. Wenn die Datei geschlossen ist, wird diese aber
> geöffnet und die richtige Zelle (A3) wird selektiert. Wenn
> ich dann unter <Bearbeiten> schaue, dann ist die Einfügen-
> Option verfügbar. Klicke ich drauf, werden die zuvor
> korrekt selektierten Daten aus der anderen Datei
> eingefügt!?!?
Wann werden die Daten denn kopiert?
Die Zwischenablage *könnte* zwischenzeitlich gelöscht oder deaktivert
worden sein.
Daher auch mein Vorschlag, die Mappe zuerst zu öffnen, die Daten dann zu
kopieren und anschliessend einzufügen - leider geht aus einem Codefragment
nicht weiter hervor, was zwischenzeiltich noch so alles passiert...
Gibst Du uns noch etwas mehr davon preis?
>Wann werden die Daten denn kopiert?
>
>Die Zwischenablage *könnte* zwischenzeitlich gelöscht
>oder deaktivert worden sein.
>Daher auch mein Vorschlag, die Mappe zuerst zu öffnen,
>die Daten dann zu kopieren und anschliessend einzufügen -
>leider geht aus einem Codefragment nicht weiter hervor,
>was zwischenzeiltich noch so alles passiert...
>
>Gibst Du uns noch etwas mehr davon preis?
*grins* natürlich, gerne. Ich habe mich nur so "bedeckt"
gehalten, weil ich nicht unnötig Code posten wollte.
Hier der gesamte Code:
*****
Sub Übertrag()
Dim iZeilen As Integer
Dim rngCUSIP As Range
Dim rngParBalance As Range
Dim rngMDundFF
Dim rngCRundSpread
Dim rngALundName
Sheets("Übertrag").Activate
Range("A3").Select
Range(Selection, Selection.End(xlDown)).Select
Set rngCUSIP = Sheets("Übertrag").Range(Selection,
ActiveCell.Offset(0, 2))
ActiveWorkbook.Names.Add Name:="rngCUSIP",
RefersTo:=rngCUSIP, Visible:=True
iZeilen = Selection.Rows.Count
Range("E3").Select
Range(Selection, ActiveCell.Offset(iZeilen - 1, 0)).Select
Set rngParBalance = Sheets("Übertrag").Range(Selection,
ActiveCell.Offset(iZeilen - 1, 0))
ActiveWorkbook.Names.Add Name:="rngParBalance",
RefersTo:=rngParBalance, Visible:=True
Range("G3").Select
Range(Selection, ActiveCell.Offset(iZeilen - 1, 1)).Select
Set rngMDundFF = Sheets("Übertrag").Range(Selection,
ActiveCell.Offset(iZeilen - 1, 1))
ActiveWorkbook.Names.Add Name:="rngMDundFF",
RefersTo:=rngMDundFF, Visible:=True
Range("J3").Select
Range(Selection, ActiveCell.Offset(iZeilen - 1, 1)).Select
Set rngCRundSpread = Sheets("Übertrag").Range(Selection,
ActiveCell.Offset(iZeilen - 1, 1))
ActiveWorkbook.Names.Add Name:="rngCRundSpread",
RefersTo:=rngCRundSpread, Visible:=True
Range("M3").Select
Range(Selection, ActiveCell.Offset(iZeilen - 1, 1)).Select
Set rngALundName = Sheets("Übertrag").Range(Selection,
ActiveCell.Offset(iZeilen - 1, 1))
ActiveWorkbook.Names.Add Name:="rngALundName",
RefersTo:=rngALundName, Visible:=True
Range
("rngCUSIP,rngParBalance,rngMDundFF,rngCRundSpread,rngALund
Name").Select
Selection.Copy
On Error Resume Next
If Not WorkbookIsOpen("Zusammenfassung.xls") Then
Workbooks.Open Filename:="C:\DATEN\Zusammenfassung.xls"
End If
Workbooks("Zusammenfassung").Activate
Sheets("Alle").Activate
Range("A65536").End(xlUp).Select
ActiveCell.Offset(1, 0).Select
ActiveSheet.Paste
End Sub
*****
Mit
**
Workbooks("Collateral_DB.xls").Sheets("Alle"). _
Range("A65536").End(xlUp).Offset(1, 0).Paste
**
für die letzten 5 Zeilen ergibt es dann den
beschriebenen "Fehler".
Zwischen der Selektierung der Daten und der Aktivierung
der neuen Datei steht imho eigentlich nichts mehr.
Sorry nochmal wegen der "Verschwiegenheit", war nicht so
gemeint.
Danke Dir für Deine Hilfe!
cu
Götz
Götz Alles schrieb am 22.06.2004
>>Daher auch mein Vorschlag, die Mappe zuerst zu öffnen,
>>die Daten dann zu kopieren und anschliessend einzufügen -
>>leider geht aus einem Codefragment nicht weiter hervor,
>>was zwischenzeiltich noch so alles passiert...
>>
>>Gibst Du uns noch etwas mehr davon preis?
>
> *grins* natürlich, gerne. Ich habe mich nur so "bedeckt"
> gehalten, weil ich nicht unnötig Code posten wollte.
Kein Problem; das ist mir schon klar und in aller Regel ja auch das
Richtige ;-9
[Range- und Namens-Zuweisung gesnippt]
> Range
> ("rngCUSIP,rngParBalance,rngMDundFF,rngCRundSpread,rngALund
> Name").Select
> Selection.Copy
>
> On Error Resume Next
> If Not WorkbookIsOpen("Zusammenfassung.xls") Then
> Workbooks.Open Filename:="C:\DATEN\Zusammenfassung.xls"
> End If
>
> Workbooks("Zusammenfassung").Activate
> Sheets("Alle").Activate
>
> Range("A65536").End(xlUp).Select
> ActiveCell.Offset(1, 0).Select
> ActiveSheet.Paste
>
> End Sub
Hier mal umgestellt der oben stehende Ausschnitt:
If Not WorkbookIsOpen("Zusammenfassung.xls") Then
Workbooks.Open Filename:="C:\DATEN\Zusammenfassung.xls"
End If
Range("rngCUSIP,rngParBalance,rngMDundFF,rngCRundSpread, _
rngALundName").Copy _
Workbooks("Collateral_DB.xls").Sheets("Alle"). _
Range("A65536").End(xlUp).Offset(1, 0)
> Zwischen der Selektierung der Daten und der Aktivierung
> der neuen Datei steht imho eigentlich nichts mehr.
Sind die kopierten Beriche zusammenhängend?
Sonst könnte dies noch eine Ursache für Probleme sein.
Für eingehendere Tests fehlt mir im Moment die Zeit, sprich ich muss noch
einen Kunden bedienen.
Morgen früh kann ich mich nochmals damit befassen.
> Danke Dir für Deine Hilfe!
Bitteschön, geschieht gerne.
>Hier mal umgestellt der oben stehende Ausschnitt:
>
>If Not WorkbookIsOpen("Zusammenfassung.xls") Then
> Workbooks.Open Filename:="C:\DATEN\Zusammenfassung.xls"
>End If
>
>Range("rngCUSIP,rngParBalance,rngMDundFF,rngCRundSpread, _
> rngALundName").Copy _
> Workbooks("Collateral_DB.xls").Sheets("Alle"). _
> Range("A65536").End(xlUp).Offset(1, 0)
>
>> Zwischen der Selektierung der Daten und der Aktivierung
>> der neuen Datei steht imho eigentlich nichts mehr.
>
>Sind die kopierten Bereiche zusammenhängend?
>Sonst könnte dies noch eine Ursache für Probleme sein.
Nein, die sind total zerpflückt. Aus dem Grund bin ich bei
der Selektion (der zu kopierenden Daten) den oben
dargestellten Weg gegangen.
Nur der Ordnung halber - überall wo "Collateral_DB" steht
sollte "Zusammenfassung.xls" stehen (tut es bei mir auch ;-
), daran liegt es also nicht ).
>Für eingehendere Tests fehlt mir im Moment die Zeit,
>sprich ich muss noch einen Kunden bedienen.
Der ist bekanntlich immer König!
>Morgen früh kann ich mich nochmals damit befassen.
Vielen herzlichen Dank. Dann bis morgen Früh.
cu
Götz
Götz Alles:
[Werte aus einer Mappe in eine andere kopieren; Copy-Paste]
Ich habe den Thread jetzt nur mal überflogen, da er recht
umfangreich ist.
Wenn ich recht vertstanden habe, was Du machst:
Warum überhaupt Copy/Paste? Du kannst doch einfach mit
set wshZiel = Workbooks("Dorthin").Worksheets("Ziel")
set wshQuelle = Workbooks("Daher").Worksheets("Quelle")
wshZiel.Range("A1:g1000").Value = _
wshQuelle.Range("A1:g1000").Value
die Daten direkt übertragen. Falls die Darstellung
umgestellt werden muß, setzt Du noch eine Array-Variable
dazwischen, die Du entsprechend manipulierst:
Array() = wshQuelle.Range("A1:g1000").Value
Array(i,j) Machwas
wshZiel.Range("A1:g1000").Value = Array()
Gruß aus Mainz
Michael
ich habe Deinen Tipp von gestern einmal wie folgt
umgesetzt:
*****
[snip - Rest wie zuvor gepostet]
Range("M3").Select
Range(Selection, ActiveCell.Offset(iZeilen - 1, 1)).Select
Set rngALundName = Sheets("Übertrag").Range(Selection,
ActiveCell.Offset(iZeilen - 1, 1))
ActiveWorkbook.Names.Add Name:="rngALundName",
RefersTo:=rngALundName, Visible:=True
On Error Resume Next
If Not WorkbookIsOpen("Collateral_DB.xls") Then
Workbooks.Open Filename:="C:\DATEN\Collateral_DB.xls"
End If
Range
("rngCUSIP,rngParBalance,rngMDundFF,rngCRundSpread,rngALund
Name").Copy _
Workbooks("Collateral_DB").Sheets("Alle").Range
("A65536").End(xlUp).Offset(1, 0)
End Sub
*****
Der letzte Teil "Range("rngCUSIP ...." scheint überhaupt
nicht verarbeitet zu werden (weder bei geöffneter noch bei
geschlossener Zieldatei). Die unzusammenhängende
Datenrange wird nicht komplett selektiert. Nur der letzte
Teil (s.o. "Range("M3").Select ..." ist markiert. Doch
auch hier ist der Copymodus nicht aktiv (klar, sollte ja
auch erst "unten" aktiviert werden).
Ich hoffe, dass Du mit meiner Beschreibung etwas anfangen
kannst.
Schon mal herzlichen Dank!
cu
Götz
>Warum überhaupt Copy/Paste? Du kannst doch einfach mit
>
>set wshZiel = Workbooks("Dorthin").Worksheets("Ziel")
>set wshQuelle = Workbooks("Daher").Worksheets("Quelle")
Muß nicht erst einmal der Pfad festgelegt werden, wo das
jeweilige Workbook steht?
>wshZiel.Range("A1:g1000").Value = _
>wshQuelle.Range("A1:g1000").Value
>
>die Daten direkt übertragen.
>Falls die Darstellung umgestellt werden muß, setzt Du
>noch eine Array-Variable dazwischen, die Du entsprechend
>manipulierst:
>
>Array() = wshQuelle.Range("A1:g1000").Value
>
>Array(i,j) Machwas
>
>wshZiel.Range("A1:g1000").Value = Array()
Ich habe mal versucht, Deinen Lösungsvorschlag umzusetzen.
Leider erhalte ich einen "Laufzeitfehler '9': Index
außerhalb des gültigen Bereiches". Die Fehlermeldung
bezieht sich auf die Zeile >set wshZiel = Workbooks
("Dorthin").Worksheets("Ziel")< was ja evtl. mit meiner
obigen Anmerkung (Pfad) zusammenhängt.
Könntest Du bitte noch einmal schauen, wo der Fehler
liegen könnte?
Götz Alles schrieb am 23.06.2004
> Hallo Thomas,
>
> ich habe Deinen Tipp von gestern einmal wie folgt
> umgesetzt:
[Code gesnippt]
> Der letzte Teil "Range("rngCUSIP ...." scheint überhaupt
> nicht verarbeitet zu werden (weder bei geöffneter noch bei
> geschlossener Zieldatei). Die unzusammenhängende
> Datenrange wird nicht komplett selektiert. Nur der letzte
> Teil (s.o. "Range("M3").Select ..." ist markiert. Doch
> auch hier ist der Copymodus nicht aktiv (klar, sollte ja
> auch erst "unten" aktiviert werden).
>
> Ich hoffe, dass Du mit meiner Beschreibung etwas anfangen
> kannst.
Nun zum verständnis des Vorganges nochmal rekapituliert:
Du möchtest unzusammenhängende Bereiche aus einer Mappe in eine andere
kopieren. Hast, respektive hattest Du mal einen Code, der funktionierte?
Wenn ich unzusammenhängende Bereiche von Hand markiere, kopiere und in eine
andere Mappe/Tabelle einfüge, laufe ich in eine Fehlermeldung - es ist so
also nicht möglich, unzusammenhängende Bereiche zu kopieren. Daher kann ich
mir, ohne es nun näher getestet zuhaben, nicht vorstellen, dass es per VBA
auf direktem Wege möglich sein soll.
Wo sollen die kopierten Bereiche beim Einfügen denn platziert werden?
Alle untereinander in einer Spalte?
Oder in derselben relativen Lage zueinander wie in der Original-Datei?
Meines Erachtens musst Du jeden Bereich einzeln kopieren, dann klappt es
auch mit der .Copy --> Destination Methode ohne Probleme.
Sorry, dass ich im Moment nicht näher auf den Code eingehe, doch es scheint
mir ein umfassenderes Versändnis über Ziel und Zweck des Vorganges
notwendig zu sein (zumindest für mich ist dem so).
>Nun zum Verständnis des Vorganges nochmal rekapituliert:
>
>Du möchtest unzusammenhängende Bereiche aus einer Mappe
>in eine andere kopieren. Hast, respektive hattest Du mal
>einen Code, der funktionierte?
Ja, mit dem geposteten Code klappt es. Aber eben nur, wenn
die Zieldatei geschlossen ist.
>Wenn ich unzusammenhängende Bereiche von Hand markiere,
>kopiere und in eine andere Mappe/Tabelle einfüge, laufe
>ich in eine Fehlermeldung - es ist so also nicht möglich,
>unzusammenhängende Bereiche zu kopieren.
Stimmt, wenn ich es per Hand versuche erhalte ich auch die
Fehlermeldung, dass dieser Befehl (Strg+C) bei nicht
zusammenhängenden Bereichen nicht möglich ist.
>Daher kann ich mir, ohne es nun näher getestet zuhaben,
>nicht vorstellen, dass es per VBA auf direktem Wege
>möglich sein soll.
>
>Wo sollen die kopierten Bereiche beim Einfügen denn
>platziert werden?
>Alle untereinander in einer Spalte?
>Oder in derselben relativen Lage zueinander wie in der
>Original-Datei?
Weder noch. Die Daten sollen ohne Lücken in der neuen
Tabelle eingefügt werden. Neu hinzukommende Daten sollen
dann unten hinzugefügt werden.
>Meines Erachtens musst Du jeden Bereich einzeln kopieren,
>dann klappt es auch mit der .Copy --> Destination Methode
>ohne Probleme.
Ist evtl. sogar auch der stabilere Weg. Denn letztlich
werden es in der Zieldatei ettliche tausend Datensätze
sein.
>Sorry, dass ich im Moment nicht näher auf den Code
>eingehe, doch es scheint mir ein umfassenderes Versändnis
>über Ziel und Zweck des Vorganges notwendig zu sein
>(zumindest für mich ist dem so).
Ich bin doch schon froh, dass Du Dir so viel Zeit für mein
Problem nimmst! Ich würde Dir die beiden Dateien auch
schicken, wenn Du willst. Allerdings will ich Dich auch
nicht zu sehr "vereinnehmen".
Nochmals herzlichen Dank für Deine Hilfe!
cu
Götz
Götz Alles schrieb am 23.06.2004
>>Du möchtest unzusammenhängende Bereiche aus einer Mappe
>>in eine andere kopieren. Hast, respektive hattest Du mal
>>einen Code, der funktionierte?
>
> Ja, mit dem geposteten Code klappt es. Aber eben nur, wenn
> die Zieldatei geschlossen ist.
Na, *das* ist ja interessant - das muss ich mir demnach etwas genauer
ansehen....
>>Wenn ich unzusammenhängende Bereiche von Hand markiere,
>>kopiere und in eine andere Mappe/Tabelle einfüge, laufe
>>ich in eine Fehlermeldung - es ist so also nicht möglich,
>>unzusammenhängende Bereiche zu kopieren.
>
> Stimmt, wenn ich es per Hand versuche erhalte ich auch die
> Fehlermeldung, dass dieser Befehl (Strg+C) bei nicht
> zusammenhängenden Bereichen nicht möglich ist.
Danke für die Bestätigung.
>>Daher kann ich mir, ohne es nun näher getestet zuhaben,
>>nicht vorstellen, dass es per VBA auf direktem Wege
>>möglich sein soll.
>>
>>Wo sollen die kopierten Bereiche beim Einfügen denn
>>platziert werden?
>>Alle untereinander in einer Spalte?
>>Oder in derselben relativen Lage zueinander wie in der
>>Original-Datei?
>
> Weder noch. Die Daten sollen ohne Lücken in der neuen
> Tabelle eingefügt werden. Neu hinzukommende Daten sollen
> dann unten hinzugefügt werden.
OK, das ist somit dann klar.
>>Meines Erachtens musst Du jeden Bereich einzeln kopieren,
>>dann klappt es auch mit der .Copy --> Destination Methode
>>ohne Probleme.
>
> Ist evtl. sogar auch der stabilere Weg. Denn letztlich
> werden es in der Zieldatei ettliche tausend Datensätze
> sein.
bei 65536 ist aber Ende der Tabelle - mehr sollten/dürfen es nicht sein...
;-)
>>Sorry, dass ich im Moment nicht näher auf den Code
>>eingehe, doch es scheint mir ein umfassenderes Versändnis
>>über Ziel und Zweck des Vorganges notwendig zu sein
>>(zumindest für mich ist dem so).
>
> Ich bin doch schon froh, dass Du Dir so viel Zeit für mein
> Problem nimmst! Ich würde Dir die beiden Dateien auch
> schicken, wenn Du willst. Allerdings will ich Dich auch
> nicht zu sehr "vereinnehmen".
...zum untersuchen und näheren Ansehen kannst dumir die beiden Tabellen
gerne senden (die Mail-Adresse 'lebt') - ich versuche dann auch den Code
wie oben beschrieben anzupssen und sezte ihn hier dann wieder in einen
Beitrag.
Götz Alles:
> >Warum überhaupt Copy/Paste? Du kannst doch einfach mit
> >
> >set wshZiel = Workbooks("Dorthin").Worksheets("Ziel")
> >set wshQuelle = Workbooks("Daher").Worksheets("Quelle")
> Muß nicht erst einmal der Pfad festgelegt werden, wo das
> jeweilige Workbook steht?
Nein, es muß halt geöffnet sein. Wenn Du das per Code
machen willst, brauchst Du natürlich den Pfad.
set wbk = workbooks.open("Pfad\und\Name.xls")
Um zu prüfen, ob es schon offen ist:
Dim wbk as Workbook, sht as Worksheet, rng As Range
For Each wbk in Workbooks
If wbk.Name = "Dorthin.xls" Then exit for
Next wbk
If wbk Is Nothing Then set wbk = _
workbooks.open("Pfad\und\Name.xls")
If wbk Is Nothing _
Then
MsgBox "Datei konnte nicht gefunden werden", _
vbExclamation
Exit Sub
end if
Set sht = wbk.WorkSheets("Ziel")
Set rng = sht.Range("A1:G1000")
rng.Value = ...
> Ich habe mal versucht, Deinen Lösungsvorschlag
> umzusetzen.
> Leider erhalte ich einen "Laufzeitfehler '9': Index
> außerhalb des gültigen Bereiches". Die Fehlermeldung
> bezieht sich auf die Zeile >set wshZiel = Workbooks
> ("Dorthin").Worksheets("Ziel")< was ja evtl. mit meiner
> obigen Anmerkung (Pfad) zusammenhängt.
Richtig. Es war wohl keine Mappe namens "Dorthin"
geöffnet. Natürlich muß es im Bsp. in "Dorthin" auch
noch ein Tabellenblatt namens "Ziel" geben.
Gruß aus Mainz
Michael
vielen Dank! Datei ist unterwegs.
cu
Götz
Eckhard Friese schrieb am 23.06.2004
> Hallo Thomas, das war ich. Gruß Eckhard
Du kannst die hier vorgestellte Funktion verwenden?
>> Muß nicht erst einmal der Pfad festgelegt werden, wo das
>> jeweilige Workbook steht?
>
>Nein, es muß halt geöffnet sein. Wenn Du das per Code
>machen willst, brauchst Du natürlich den Pfad.
Gut, hierfür ist im Modul der Code bereits eingearbeitet.
Ich versuche mal ob es klappt, wenn ich die Anweisung
unter meine "Geöffnet?" Abfrage stelle.
[snip]
>> Ich habe mal versucht, Deinen Lösungsvorschlag
>> umzusetzen.
>> Leider erhalte ich einen "Laufzeitfehler '9': Index
>> außerhalb des gültigen Bereiches". Die Fehlermeldung
>> bezieht sich auf die Zeile >set wshZiel = Workbooks
>> ("Dorthin").Worksheets("Ziel")< was ja evtl. mit meiner
>> obigen Anmerkung (Pfad) zusammenhängt.
>
>Richtig. Es war wohl keine Mappe namens "Dorthin"
>geöffnet. Natürlich muß es im Bsp. in "Dorthin" auch
>noch ein Tabellenblatt namens "Ziel" geben.
*grins* Das ist schon klar. Ich denke mal, dass ich die
notwendigen Anpassungen vorgenommen habe.
Danke noch mal für Deinen Tipp. Ich schaue mal, wie weit
ich jetzt komme.
cu
Götz
ich habe den Code jetzt mal wie folgt eingebaut:
*****
[snip]
Range
("rngCUSIP,rngParBalance,rngMDundFF,rngCRundSpread,rngALund
Name").Select
Selection.Copy
On Error Resume Next
If Not WorkbookIsOpen("Collateral_DB.xls") Then
Workbooks.Open Filename:="C:\DATEN\Collateral_DB.xls"
End If
'neu:
Set wshZiel = Workbooks("Collateral_DB").Worksheets("Alle")
Set wshQuelle = Workbooks("Test Trusteereport Übertrag
2").Worksheets("Übertrag")
wshZiel.Range("A3").Value = _
wshQuelle.Range
("rngCUSIP,rngParBalance,rngMDundFF,rngCRundSpread,rngALund
Name").Value
'neu Ende
*****
Die Daten werden nicht kopiert. Wahrscheinlich liegt es
daran, dass ich bei "wshZiel.Range("A3").Value = _" mit
der Range "A3" nicht präzise genug bin. Da ich allerdings
nicht im Vorfeld weiß, wie viele Daten kopiert werden,
kann ich hier nichts angeben. Es ändert auch nichts, wenn
ich "wshZiel.Range("A3:J65000").Value ..." eingebe. Auch
dann werden keine Daten eingefügt.
Vieleicht hast Du ja noch einen Tipp, woran das liegen
könnte.
Vielen Dank schon einmal.
cu
Götz
Götz Alles:
> [snip]
Wenn Du Dir das mal genauer anschauen würdest, bräuchtest
Du kein On Error Resume Next mehr, was jeden projektweiten
Error-Handler kaputtmacht. Die selbstgemachte
WorkbookIsOpen-Funktion ist kein gutes Beispiel, wie man
es machen sollte, und bei dem, was Du gesnipt hast, auch
völlig überflüssig, da die Prüfung auf geöffnete Dateien
dort ohne On-Error-Krücke schon eingebaut ist.
> Range ("rngCUSIP,rngParBalance,rngMDundFF,rngCRundSpread,
> rngALund Name").Select
> Selection.Copy
Das Select ist ebenso wie Selection.Copy bei dieser Methode
gänzlich unnötig. Daten müssen *nicht* selektiert
werden, um mit ihnen zu arbeiten.
> On Error Resume Next
> If Not WorkbookIsOpen("Collateral_DB.xls") Then
> Workbooks.Open Filename:="C:\DATEN\Collateral_DB.xls"
> End If
>
> 'neu:
> Set wshZiel = Workbooks("Collateral_DB").Worksheets
> ("Alle")
> Set wshQuelle = Workbooks("Test Trusteereport Übertrag
> 2").Worksheets("Übertrag")
>
> wshZiel.Range("A3").Value = _
> wshQuelle.Range"rngCUSIP,rngParBalance,rngMDundFF,
> rngCRundSpread,rngALundName").Value
> 'neu Ende
> *****
So geht das nicht. Die Ranges von Quelle und Ziel müssen
von den Abmessungen her exakt übereinstimmen.
Falls das nicht gewünscht ist, über Array-Operationen
umstellen.
> wshZiel.Range("A3").Value = _
> wshQuelle.Range
>("rngCUSIP,rngParBalance,rngMDundFF,rngCRundSpread, _
> rngALundName").Value
geht nur wenn der QuellRange auch nur eine Zelle umfaßt.
Außerdem sieht mir "rngCUSIP,rngParBalance,..." nicht
nach einer gültigen Range-Angabe aus.
Um die Größe von Ranges dynamisch festzulegen, gibt
es Dutzende Methoden. Siehe OH: Cells, Resize, End,
Range.Range, SpecialCells etc. etc.
Mach Dir doch erstmal zum Schauen eine Mappe1 und Mappe2,
wo Du nach der genannten Methode
Workbooks("Mappe1").Worksheets("Tabelle1").
Range("B3:D5").Value
nach
Workbooks("Mappe2").Worksheets("Tabelle1").
Range("E7:G9").Value
überträgst, damit Du ein Gefühl für das ganze bekommst.
Gruß aus Mainz
Michael
Thomas Ramel schrieb am 23.06.2004
>>>Du möchtest unzusammenhängende Bereiche aus einer Mappe
>>>in eine andere kopieren. Hast, respektive hattest Du mal
>>>einen Code, der funktionierte?
>>
>> Ja, mit dem geposteten Code klappt es. Aber eben nur, wenn
>> die Zieldatei geschlossen ist.
>
> Na, *das* ist ja interessant - das muss ich mir demnach etwas genauer
> ansehen....
In der Tat ist es so, dass auf diese Weise 'zusammengefasste'
unzusammenhängende Bereiche mittels der Activrsheet.Paste-Methode diretk in
ein Tabellenblatt kopiert werden können.
Offenbar klappt es aber nur, wenn das Tabellenblatt und die entsprechende
Zelle auch wirklich selektiert werden.
Von Hand ist dies, wie schon bestätigt, nicht möglich.
Wie versprochen, hier der überarbeitete Code. Er folgt im Grossen und
ganzen den von Michael genannten Wegen.
Dir Dunkion zur Prüfung, ob die Mappe geöffnet ist, wird nach wie vor
benötigt.
Sub Übertrag_tr()
Dim lngZeilen As Long
Dim wsQuelle As Worksheet
Dim wsZiel As Worksheet
Dim rngZiel As Range
If Not WorkbookIsOpen("Collateral_DB.xls") Then
Workbooks.Open Filename:=ThisWorkbook.Path & "\Collateral_DB.xls"
End If
Set wsQuelle = Workbooks(ThisWorkbook.Name).Worksheets("Übertrag")
Set wsZiel = Workbooks("Collateral_DB.xls").Worksheets("Alle")
Set rngZiel = wsZiel.Range("A65536").End(xlUp).Offset(1, 0)
lngZeilen = wsQuelle.Range("A3").End(xlDown).Row - 2
rngZiel.Resize(lngZeilen, 3).Value = _
wsQuelle.Range("A3").Resize(lngZeilen, 3).Value
rngZiel.Offset(0, 3).Resize(lngZeilen, 1).Value = _
wsQuelle.Range("E3").Resize(lngZeilen, 1).Value
rngZiel.Offset(0, 4).Resize(lngZeilen, 1).Value = _
wsQuelle.Range("G3").Resize(lngZeilen, 1).Value
rngZiel.Offset(0, 6).Resize(lngZeilen, 2).Value = _
wsQuelle.Range("J3").Resize(lngZeilen, 2).Value
rngZiel.Offset(0, 8).Resize(lngZeilen, 2).Value = _
wsQuelle.Range("M3").Resize(lngZeilen, 2).Value
End Sub
Thomas Ramel:
> Wie versprochen, hier der überarbeitete Code. Er folgt
> im Grossen und ganzen den von Michael genannten Wegen.
> Dir Dunkion zur Prüfung, ob die Mappe geöffnet ist, wird
> nach wie vor benötigt.
>
> If Not WorkbookIsOpen("Collateral_DB.xls") Then
Gerade diese Funktion solltest Du Dir nochmal gut
überlegen. Ich weiß nicht, ob Du meinen Hinweis mit dem
Error-Handling gelesen hast. Wenn die Prozedur von anderen
Prozeduren aufgerufen wird, macht ein On Error Resume Next
die nach oben weiterzureichenden Err.Numbers kaputt.
Wenn Du Dir das hier nochmal anschaust:
| For Each wbk in Workbooks
| If wbk.Name = "DieMappe.xls" Then exit for
| Next wbk
|
| If wbk Is Nothing Then set wbk = _
| workbooks.open("Pfad\und\DieMappe.xls")
|
| If wbk Is Nothing _
| Then
| MsgBox "Datei konnte nicht gefunden werden", _
| vbExclamation
| Exit Sub
| end if
Das stellt sicher, daß wbk einen gültigen Verweis
auf DieMappe.xls enthält, wenn sie schon geöffnet
ist, und löst, auch wenn /gar keine/ Mappe offen ist,
keinen Error aus.
Wenn DieMappe.xls nicht geöffnet ist, wird sie
geöffnet und wbk zugewiesen.
Falls der Pfad nicht stimmt, haben wir keine Chance,
und es wird nach Meldung abgebrochen.
Nach dem If-Block enthält wbk also in jedem Fall einen
gültigen Verweis auf die Mappe - ohne Error, also auch
ohne ein kaskadierendes Error-Handling in Elter-Prozeduren
zu unterbrechen. Eine Boolean-Variable IsOpen o. ä.
ist dann eigentlich unnötig.
Gruß aus Mainz
Michael
Michael Zimmermann schrieb am 23.06.2004
>> If Not WorkbookIsOpen("Collateral_DB.xls") Then
>
> Gerade diese Funktion solltest Du Dir nochmal gut
> überlegen. Ich weiß nicht, ob Du meinen Hinweis mit dem
> Error-Handling gelesen hast. Wenn die Prozedur von anderen
> Prozeduren aufgerufen wird, macht ein On Error Resume Next
> die nach oben weiterzureichenden Err.Numbers kaputt.
Interesse geweckt!
Kannst Du mir kurz ein Szenario hochziehen, welches das Gesagte
untermauert?
Die OnError-'Masche' sollte bloss das durchlaufen aller geöffneten
Workbooks umgehen.
Doch eine sichere Methode ist mir allemal lieber; dhaer interessiert mir
die gemachte Aussage.
>| For Each wbk in Workbooks
>| If wbk.Name = "DieMappe.xls" Then exit for
>| Next wbk
>|
>| If wbk Is Nothing Then set wbk = _
>| workbooks.open("Pfad\und\DieMappe.xls")
>|
>| If wbk Is Nothing _
>| Then
>| MsgBox "Datei konnte nicht gefunden werden", _
>| vbExclamation
>| Exit Sub
>| end if
Die Funktionsweise und das Ergebnis ist mir klar.
Thomas Ramel:
> Michael Zimmermann schrieb am 23.06.2004
> >> If Not WorkbookIsOpen("Collateral_DB.xls") Then
> >
> > Gerade diese Funktion solltest Du Dir nochmal gut
> > überlegen. Ich weiß nicht, ob Du meinen Hinweis mit dem
> > Error-Handling gelesen hast. Wenn die Prozedur von
> > anderen Prozeduren aufgerufen wird, macht ein
> > On Error Resume Next die nach oben weiterzureichenden
> > Err.Numbers kaputt.
>
> Interesse geweckt!
>
> Kannst Du mir kurz ein Szenario hochziehen, welches das
> Gesagte untermauert?
Okay. Siehe unten.
> Die OnError-'Masche' sollte bloss das durchlaufen aller
> geöffneten Workbooks umgehen.
Schon klar. Aber warum? Performance? Damit Du von einer
For-Next-Schleife auf einem halbwegs modernen Rechner
überhaupt etwas merkst, müßte sie über so viele Workbooks
laufen, daß Excel längst abgestürzt wäre...
;-)
Jetzt aber zum Error Handling.
Dazu muß man wissen, daß eine Prozedur, wenn sie keine
On-Error-Anweisung enthält, den Fehler in die aufrufende
Mutterprozedur weiterreicht. Das macht auch Sinn, da
ich dadurch nicht 30 Div-0-Handler in 30 kleinen
Prozeduren brauche, sondern genau einen.
Also: Mutter ruft Kind auf, Kind ruft Enkel auf, etc.
Kind und Enkel sollten *gar keinen* ErrorHandler enthalten.
Sie reichen dann ihren Fehlercode sukzessive nach oben,
bis ein aktivierter Handler angetroffen wird. Wenn der
zwischendrin On Error Resume Next oder On Error Resume
Next/Goto 0 heißt, sind alle untergeordeneten Fehlercodes
verloren.
Sub Mutter()
Dim x As Long
On Error GoTo EHdl
Kind 0 'Fehler 11: Div 0 in Kind
x = 2E+15 'Fehler 6: Überlauf
EHdl:
If Err.Number > 0 _
Then
MsgBox Err.Number & " " & _
Err.Description
Resume Next
end if
End Sub
Sub Kind(x As Long)
'On Error Resume Next '***
x = 1 / x
'On Error GoTo 0 '***
End Sub
Schalte mal Resume Next/GoTo 0 in verschiedenen
Kombinationen ein und aus.
Der zentrale Handler in Mutter muß Fehler 11 und 6
melden. Wenn Resume Next/GoTo 0 in Kind aktiviert
sind, unterbleibt 11, was unerwünscht ist.
Wenn Du zum Spaß auch mal x = 2E+15 auskommentierst,
kommt plötzlich wieder ein Fehler von unten, falls nicht
auch noch On Error Goto 0 gesetzt ist. Das Verhalten des
Codes wird ziemlich unberechenbar.
Falls Kind noch Enkel aufruft, werden je nach
Code-Ablauf dessen Errors auch in Kind verschluckt
und erreichen nie den differenzierten Handler in
Mutter.
Wenn man in Prozeduren Fehler lokal "umgehen" will,
fängt man den potentiellen Fehler besser konservativ
ab. Beispiel sicheres Teilen (wenn der Divisor = 0
ist, soll der NULL-Wert herauskommen, sonst der
Quotient a/b):
Nicht
On Error Resume Next
x = Null
x = a/b 'b könnte 0 sein
On Error Goto 0
sondern eher so etwas wie
If b = 0 Then x = Null: Exit Sub
x = a/b
oder noch besser
x = a/(-b*((b <> 0) Or Null))
bzw. wenn b Long, einfacher
x = a/(b Or Null)
Es gibt natürlich Einzelfälle, wo man keine bösen Folgen
erwarten muß, wenn man On Error Resume Next benutzt,
z. B. in einer Stand-Alone-Prozedur.
Ein zentrales Error-Handling in ausgwachsenen Projekten
wird durch On Error Resume Next aber nicht gefördert...
Gruß aus Mainz
Michael
Michael Zimmermann schrieb am 24.06.2004
>>> Wenn die Prozedur von anderen Prozeduren aufgerufen wird, macht ein On
>>> Error Resume Next die nach oben weiterzureichenden Err.Numbers kaputt.
>>
>> Interesse geweckt!
>>
>> Kannst Du mir kurz ein Szenario hochziehen, welches das
>> Gesagte untermauert?
>
> Okay. Siehe unten.
>
>> Die OnError-'Masche' sollte bloss das durchlaufen aller
>> geöffneten Workbooks umgehen.
>
> Schon klar. Aber warum? Performance? Damit Du von einer
> For-Next-Schleife auf einem halbwegs modernen Rechner
> überhaupt etwas merkst, müßte sie über so viele Workbooks
> laufen, daß Excel längst abgestürzt wäre...
> ;-)
Einerseits war es die Performance (die aber echt nich stark ins Gewicht
fällt, wie ich auch mal getestet habe); andererseits auch die 'Masche', mal
was objektorientiertes anstelle einer 'ollen' For...Each-Schleife zu
machen... ;-)
> Dazu muß man wissen, daß eine Prozedur, wenn sie keine
> On-Error-Anweisung enthält, den Fehler in die aufrufende
> Mutterprozedur weiterreicht.
Man(n) hat das soeben zur Kenntnis gonommen, und wird es künftig
(hoffentlich) wissen....
> Also: Mutter ruft Kind auf, Kind ruft Enkel auf, etc.
>
> Kind und Enkel sollten *gar keinen* ErrorHandler enthalten.
> Sie reichen dann ihren Fehlercode sukzessive nach oben,
> bis ein aktivierter Handler angetroffen wird. Wenn der
> zwischendrin On Error Resume Next oder On Error Resume
> Next/Goto 0 heißt, sind alle untergeordeneten Fehlercodes
> verloren.
[Verebungslehre gesnippt] ;-)
> Es gibt natürlich Einzelfälle, wo man keine bösen Folgen
> erwarten muß, wenn man On Error Resume Next benutzt,
> z. B. in einer Stand-Alone-Prozedur.
Die Funktion zur Prüfung, ob ein Workbook geöffnet ist, war mal als eine
solche Gedacht.
> Ein zentrales Error-Handling in ausgwachsenen Projekten
> wird durch On Error Resume Next aber nicht gefördert...
Ob all dem Gesagten (und auch Getesteten) werde ich die Function etwas
umschreiben und mir für künftige Ratschläge die Essenz hinter die Ohren
schreiben.
Michael; vielen Dank für deine Interventionen in diese Sache!
Es war mir eine Freude, neues und (mir bisher) unbekanntes Gebiet zu
erforschen und die gewonnenen Erkentnisse in Zukunft einzubrigen.
Das eben Erlebte ist für mich stetige Motivation, in der NG einen Anteil zu
haben - ich lerne dazu und erweitere meinen Horizont.
In diesem Sinne: auf weiterhin gute Zusammenarbeit hier in der NG.
Thomas Ramel:
> Einerseits war es die Performance (die aber echt nich
> stark ins Gewicht fällt, wie ich auch mal getestet habe);
> andererseits auch die 'Masche', mal was
> objektorientiertes anstelle einer 'ollen' For...Each-
> Schleife zu machen... ;-)
For Each ist keine Schande ;-) Im Gegensatz zu For <Zähler>
ist es eigentlich sogar sehr objektorientiert, da es ja
ein Collection-*Objekt* mit *Objekten* als Members mittels
*Objekt*-Enumeration durchläuft.
Noch objektiger geht's kaum. ;-)
> ...
> Das eben Erlebte ist für mich stetige Motivation, in der
> NG einen Anteil zu haben - ich lerne dazu und erweitere
> meinen Horizont.
>
> In diesem Sinne: auf weiterhin gute Zusammenarbeit hier
> in der NG.
Danke schön, ich werd mir Mühe geben. ;-)
Gruß aus Mainz
Michael