Discussion:
Zwischenablage: Mitkopieren von Spalten-Überschriften
(zu alt für eine Antwort)
Stefan Heinrichs
2007-11-15 15:16:01 UTC
Permalink
Hallo,

ich arbeite mit Access 2003.

Wenn ich in Access Zeilen aus einer Tabelle oder Abfrage (in die
Zwischenablage) kopiere, kopiert Access stets auch die
Spalten-Überschriftenzeile mit. Da ich die kopierten Zeilen direkt in SAP
einfügen möchte, ist die Überschriftenzeile sehr störend.
Wie kann ich es ausschalten, daß Access stets auch die Überschrift kopiert?

Würde mich über einen Hinweis sehr freuen.
Thomas Möller
2007-11-15 15:25:51 UTC
Permalink
Hallo Stefan,
Post by Stefan Heinrichs
Wenn ich in Access Zeilen aus einer Tabelle oder Abfrage (in die
Zwischenablage) kopiere, kopiert Access stets auch die
Spalten-Überschriftenzeile mit. Da ich die kopierten Zeilen direkt in
SAP einfügen möchte, ist die Überschriftenzeile sehr störend.
Wie kann ich es ausschalten, daß Access stets auch die Überschrift kopiert?
evtl. bringt Dich das hier weiter:
http://support.microsoft.com/kb/198917/de


HTH
--
Thomas

Homepage: www.Team-Moeller.de
Stefan Heinrichs
2007-11-15 15:34:00 UTC
Permalink
Post by Thomas Möller
http://support.microsoft.com/kb/198917/de
Leider möchte ich den Inhalt von viel mehr als einer Zelle kopieren (ca. 50
ZEILEN mit 10 Spalten).
Damit hilft diese Möglichkeit mir nicht weiter.
Michael Zimmermann
2007-11-15 15:45:29 UTC
Permalink
Hallo!
Stefan Heinrichs
Post by Stefan Heinrichs
Wenn ich in Access Zeilen aus einer Tabelle oder
Abfrage (in die Zwischenablage) kopiere, kopiert Access
stets auch die Spalten-Überschriftenzeile mit. Da ich
die kopierten Zeilen direkt in SAP einfügen möchte, ist
die Überschriftenzeile sehr störend. Wie kann ich es
ausschalten, daß Access stets auch die
Überschrift kopiert?
http://support.microsoft.com/kb/198917/de
Kaum. Da wird genau das Verhalten beschrieben, über das
sich Stefan beschwert. Zeile <> Zelle ;-)

Mir würde dazu auf Anhieb einfallen:

Zwischenablage selbst mit API füllen: Viel Arbeit, aber
der fertige Code läßt sich ggf. Jörg Ostendorp aus den
Rippen leiern.

Die Datenübertragung programmieren. Die Benutzung der
Zwischenablage ist erstens unsicher und zweitens unwürdig
in einer DB.

Quick and Dirty (und es ist seehr schmutzig): Die Daten in
Excel einfügen, ohne die Beschriftungszeile nochmal
markieren und kopieren und ab dafür.

Den letzten Vorschlag mache ich nur, um damit meinem
Image als theoretisierender Prinzipienreiter
entgegenzuwirken. ;-)

Davon abgesehen ist Lösung 2 natürlich theoretisch wie
praktisch und prizipiell der Königsweg.

Gruß aus Mainz
Michael
unknown
2007-11-15 18:04:59 UTC
Permalink
Hallo zusammen,
Post by Michael Zimmermann
Stefan Heinrichs
Post by Stefan Heinrichs
Wenn ich in Access Zeilen aus einer Tabelle oder
Abfrage (in die Zwischenablage) kopiere, kopiert Access
stets auch die Spalten-Überschriftenzeile mit. Da ich
die kopierten Zeilen direkt in SAP einfügen möchte, ist
die Überschriftenzeile sehr störend. Wie kann ich es
ausschalten, daß Access stets auch die
Überschrift kopiert?
http://support.microsoft.com/kb/198917/de
Kaum. Da wird genau das Verhalten beschrieben, über das
sich Stefan beschwert. Zeile <> Zelle ;-)
Zwischenablage selbst mit API füllen: Viel Arbeit, aber
der fertige Code läßt sich ggf. Jörg Ostendorp aus den
Rippen leiern.
Ich darf mal auf folgenden Thread verweisen, an dem Du ja auch nicht ganz
schuldlos warst:

http://groups.google.de/group/microsoft.public.de.access/browse_thread/thread/bc9e4f652bc7e617/d9cf1473cfb33d89#d9cf1473cfb33d89

Den Kram mit den Spaltenüberschriften kann man da ja rauslöschen. Auswahl
der Datensätze dann ggf. wie in www.donkarl.com?FAQ4.40 beschrieben.
--
Grüßle vom Bodensee
Jörg Ostendorp

Access-FAQ: www.donkarl.com
Michael Zimmermann
2007-11-15 19:42:33 UTC
Permalink
Hallo!

Jörg Ostendorp
Post by unknown
Ich darf mal auf folgenden Thread verweisen, an dem Du ja
http://groups.google.de/group/microsoft.public.de.access/browse_thread/thread/bc9e4f652bc7e617/d9cf1473cfb33d89#d9cf1473cfb33d89
Da habe ich übrigens noch ein kleines Präsent für Dich:

Du kannst in der Schleife, die den Puffer füllt,

MidB$(t, p, l) = fld(j).Value & tRsSep 'bzw. tFldSep

ersetzen durch

RtlMoveMemoryVal StrPtr(t) + p, _
StrPtr(fld(j).Value & tRsSep), _
l 'bzw. tFldSep

Macht genau dasselbe, sollte aber einem APIstel wie Dir
viel besser gefallen. Die Deklaration von RtlMoveMemory
weißt Du ja eh' auswendig. ;-)

Gruß aus Mainz
Michael
unknown
2007-11-15 20:39:49 UTC
Permalink
Hallo Michael,
Post by Michael Zimmermann
Post by unknown
Ich darf mal auf folgenden Thread verweisen, an dem Du ja
http://groups.google.de/group/microsoft.public.de.access/browse_thread/thread/bc9e4f652bc7e617/d9cf1473cfb33d89#d9cf1473cfb33d89
Danke :-)
Post by Michael Zimmermann
Du kannst in der Schleife, die den Puffer füllt,
MidB$(t, p, l) = fld(j).Value & tRsSep 'bzw. tFldSep
ersetzen durch
RtlMoveMemoryVal StrPtr(t) + p, _
StrPtr(fld(j).Value & tRsSep), _
l 'bzw. tFldSep
Macht genau dasselbe, sollte aber einem APIstel wie Dir
viel besser gefallen. Die Deklaration von RtlMoveMemory
weißt Du ja eh' auswendig. ;-)
Irgendwie ist das jetzt ein echter Tiefschlag für mich :-(
RtlMoveMemory ist bei mir in der schnellsten Variante immer noch doppelt so
langsam wie MidB$. Noch dazu kann man sich viele Variante ausdenken, in
denen die Performance dann rasant in den Keller geht. Allein eine
Deklaration von Source und Destination als String anstelle von Any
verlangsamt das Ganze um den Faktor 10.
Bin da etwas verblüfft drüber. Kannst Du das bestätigen?

(Getestet mit QueryPerformanceCounter/-Frequency. Einfache Befüllung eines
Puffers (Space$(10000)) in einer for next-Schleife. Zeitnahme unmittelbar
vor dem for und nach dem next, also ohne Dimensionierungen etc.)
--
Grüßle vom Bodensee
Jörg Ostendorp

Access-FAQ: www.donkarl.com
Michael Zimmermann
2007-11-15 21:13:37 UTC
Permalink
Hallo!
Post by unknown
Irgendwie ist das jetzt ein echter Tiefschlag für mich :-(
RtlMoveMemory ist bei mir in der schnellsten Variante
immer noch doppelt so langsam wie MidB$. Noch dazu kann
man sich viele Variante ausdenken, in denen die
Performance dann rasant in den Keller geht. Allein eine
Deklaration von Source und Destination als String
^^^^^^
Post by unknown
anstelle von Any verlangsamt das Ganze um den Faktor 10.
Kerl, was treibst Du da?!?

Public Declare Sub RtlMoveMemoryVal _
Lib "Kernel32" _
Alias "RtlMoveMemory" ( _
ByVal pDest As Long, _
ByVal pSrc As Long, _
ByVal Bytes As Long)

Destination und Source sind *Speicheradressen*, die müssen
*Long* sein. Was wilst Du da mit einem String? Mit as Any
sind sie auch Long aber ByRef. Das braucht bei der Funktion
aber keiner. Das sind die einzigen beiden Varianten, die
überhaupt vorgesehen sind.

Um welchen Variablentyp es sich handelt, spielt bei
RtlMoveMemory keine Rolle; es wird immer mit *Adressen*
(=Zahlen) hantiert. Daß Dir das mit String nicht vom
Compiler um die Ohren gehauen wurde, verdankst Du
wahrscheinlich nur der großmütigen, aber langsamen
DAUtomatischen Typkonvertierung von VB. :-)
Post by unknown
Bin da etwas verblüfft drüber. Kannst Du das bestätigen?
Probier es mal mit dieser Deklaration oben. Ich würde
erwarten, daß es dann in etwa gleich schnell sein sollte,
da MidB$ eigentlich die gleiche Funktionalität aufruft.

Es könnte allenfalls sein, daß man StrPtr auslagern könnte,
d. h. einmalig einem Long zuweist, da sich z. B. die Adresse
der Puffervariablen nicht ändert. Entsprechend StrPtr(fld)
in die äußere Schleife. Ggf. behandelt Mid das intern auch
so. Das ist aber nur eine Vermutung. Damit würde
unterbunden, daß StrPtr unnötig ausgeführt wird.

Gruß aus Mainz
Michael
unknown
2007-11-15 21:46:44 UTC
Permalink
Hallo Michael,
Post by Michael Zimmermann
Post by unknown
Irgendwie ist das jetzt ein echter Tiefschlag für mich :-(
RtlMoveMemory ist bei mir in der schnellsten Variante
immer noch doppelt so langsam wie MidB$. Noch dazu kann
man sich viele Variante ausdenken, in denen die
Performance dann rasant in den Keller geht. Allein eine
Deklaration von Source und Destination als String
^^^^^^
Post by unknown
anstelle von Any verlangsamt das Ganze um den Faktor 10.
Kerl, was treibst Du da?!?
Testen.
Post by Michael Zimmermann
Public Declare Sub RtlMoveMemoryVal _
Lib "Kernel32" _
Alias "RtlMoveMemory" ( _
ByVal pDest As Long, _
ByVal pSrc As Long, _
ByVal Bytes As Long)
Destination und Source sind *Speicheradressen*, die müssen
*Long* sein. Was wilst Du da mit einem String?
Eigentlich nur Testen, was passiert, wenn das als String deklariert ist
(Experimentelle Mathematik ;-) )
Post by Michael Zimmermann
Mit as Any
sind sie auch Long aber ByRef. Das braucht bei der Funktion
aber keiner. Das sind die einzigen beiden Varianten, die
überhaupt vorgesehen sind.
Um welchen Variablentyp es sich handelt, spielt bei
RtlMoveMemory keine Rolle; es wird immer mit *Adressen*
(=Zahlen) hantiert. Daß Dir das mit String nicht vom
Compiler um die Ohren gehauen wurde, verdankst Du
wahrscheinlich nur der großmütigen, aber langsamen
DAUtomatischen Typkonvertierung von VB. :-)
Jau, wie winde ich mich da jetzt bloß wieder raus....
Muß eine Abart der Amaurosis scachistica gewesen sein :-(
Post by Michael Zimmermann
Post by unknown
Bin da etwas verblüfft drüber. Kannst Du das bestätigen?
Probier es mal mit dieser Deklaration oben. Ich würde
erwarten, daß es dann in etwa gleich schnell sein sollte,
da MidB$ eigentlich die gleiche Funktionalität aufruft.
Es könnte allenfalls sein, daß man StrPtr auslagern könnte,
d. h. einmalig einem Long zuweist, da sich z. B. die Adresse
der Puffervariablen nicht ändert. Entsprechend StrPtr(fld)
in die äußere Schleife. Ggf. behandelt Mid das intern auch
so. Das ist aber nur eine Vermutung. Damit würde
unterbunden, daß StrPtr unnötig ausgeführt wird.
Gerade getestet. Bringt ein wenig was, aber midB ist immer noch deutlich
schneller.
--
Grüßle vom Bodensee
Jörg Ostendorp

Access-FAQ: www.donkarl.com
Michael Zimmermann
2007-11-15 22:04:11 UTC
Permalink
Hallo!
Post by unknown
Gerade getestet. Bringt ein wenig was, aber midB ist
immer noch deutlich ...
Interessehalber: "Deutlich" als Zahl?
Post by unknown
... schneller.
Vielleicht gereicht es Dir zum Trost, daß es mit der
API-Funktion wenigstens deutlich kryptischer ist? ;-)

Gruß aus Mainz
Michael
unknown
2007-11-16 08:53:17 UTC
Permalink
Hallo Michael,
Post by Michael Zimmermann
Post by unknown
Gerade getestet. Bringt ein wenig was, aber midB ist
immer noch deutlich ...
Interessehalber: "Deutlich" als Zahl?
Post by unknown
... schneller.
Bezieht sich Deine Frage darauf, ob ich das jetzt ordentlich als Zahl
deklariert ;-( habe oder möchtest Du eine quantitative Angabe?

Also, Deklaration mit ByVal as Long

Test:
Eine einzelne For-Next-Schleife, in der ein Puffer mit 10.000 Stellen
gefüllt wird.

Zeitdauer:
- MidB$ durchschnittlich etwa 1,4 ms

RtlMoveMemory mit StrPtr(Buffer)
- vor der Schleife etwa 2,4 ms / + 71 %
- in der Schleife 3,3 ms / + 136 %
--
Grüßle vom Bodensee
Jörg Ostendorp

Access-FAQ: www.donkarl.com
Henry Habermacher
2007-11-20 03:53:27 UTC
Permalink
Hallo Stefan
Post by Stefan Heinrichs
Wenn ich in Access Zeilen aus einer Tabelle oder Abfrage (in die
Zwischenablage) kopiere, kopiert Access stets auch die
Spalten-Überschriftenzeile mit. Da ich die kopierten Zeilen direkt in SAP
einfügen möchte, ist die Überschriftenzeile sehr störend.
Wie kann ich es ausschalten, daß Access stets auch die Überschrift kopiert?
Scheib' eine Funktion mir der Du die erste Zeile des Clipboard rauslöschst.
Rufe diese z.B. über einen Buttonclick oder über eine Autokeys Makro auf und
kopiere danach die Daten ins SAP.

Hier, wie so eine Funktion aussehen könnte:
Public Function Clipboard_StripHeader()
Dim strCB As String
Dim I As Long
strCB = ClipBoard_GetData()
I = InStr(strCB, vbCrLf)
If I < Len(strCB) Then
ClipBoard_SetData (Mid(strCB, I + 2))
Else
MsgBox ("Keine Headerzeile gefunden")
End If
End Function

Diese benötigt zwei Funktionen aus der KB:
http://support.microsoft.com/?kbid=210216
http://support.microsoft.com/?kbid=210213

Hier einfachheitshalber alles zusammengefasst zum Einfügen in ein neues
leeres Standard Modul. Verwendung:
- Zeilen in Tabelle/Abfrage in Zwischenablage kopieren
- Funktion Clipboard_StripHeader() aufrufen
- Zwischenablage in Zielumgebung einfügen

'code follows here

Option Compare Database
Option Explicit

Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) _
As Long
Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) _
As Long
Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, _
ByVal dwBytes As Long) As Long
Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) _
As Long
Declare Function CloseClipboard Lib "User32" () As Long
Declare Function OpenClipboard Lib "User32" (ByVal hwnd As Long) _
As Long
Declare Function EmptyClipboard Lib "User32" () As Long
Declare Function lstrcpy Lib "kernel32" (ByVal lpString1 As Any, _
ByVal lpString2 As Any) As Long
Declare Function SetClipboardData Lib "User32" (ByVal wFormat _
As Long, ByVal hMem As Long) As Long
Declare Function GetClipboardData Lib "User32" (ByVal wFormat As _
Long) As Long

Public Const GHND = &H42
Public Const CF_TEXT = 1
Public Const MAXSIZE = 4096

' contains code from Microsoft that may be copyrighted
' source:
' - http://support.microsoft.com/?kbid=210216
' - http://support.microsoft.com/?kbid=210213

Function ClipBoard_SetData(MyString As String)
Dim hGlobalMemory As Long, lpGlobalMemory As Long
Dim hClipMemory As Long, X As Long
hGlobalMemory = GlobalAlloc(GHND, Len(MyString) + 1)
lpGlobalMemory = GlobalLock(hGlobalMemory)
lpGlobalMemory = lstrcpy(lpGlobalMemory, MyString)
If GlobalUnlock(hGlobalMemory) <> 0 Then
MsgBox "Could not unlock memory location. Copy aborted."
GoTo OutOfHere2
End If
If OpenClipboard(0&) = 0 Then
MsgBox "Could not open the Clipboard. Copy aborted."
Exit Function
End If
X = EmptyClipboard()
hClipMemory = SetClipboardData(CF_TEXT, hGlobalMemory)
OutOfHere2:
If CloseClipboard() = 0 Then
MsgBox "Could not close Clipboard."
End If
End Function

Function ClipBoard_GetData()
Dim hClipMemory As Long
Dim lpClipMemory As Long
Dim MyString As String
Dim RetVal As Long
If OpenClipboard(0&) = 0 Then
MsgBox "Zwischenablage kann nicht geöffnet werden, " _
& "eventuell durch andere Anwendung geöffnet."
Exit Function
End If
hClipMemory = GetClipboardData(CF_TEXT)
If IsNull(hClipMemory) Then
MsgBox "Speicher konnte nicht zugewiesen werden"
GoTo OutOfHere
End If
lpClipMemory = GlobalLock(hClipMemory)
If Not IsNull(lpClipMemory) Then
MyString = Space$(MAXSIZE)
RetVal = lstrcpy(MyString, lpClipMemory)
RetVal = GlobalUnlock(hClipMemory)
MyString = Mid(MyString, 1, InStr(1, MyString, Chr$(0), 0) - 1)
Else
MsgBox "Speicher, aus dem Zeichenfolge kopiert werden soll, konnte" _
& "nicht gesperrt werden."
End If
OutOfHere:
RetVal = CloseClipboard()
ClipBoard_GetData = MyString
End Function

Public Function Clipboard_StripHeader()
Dim strCB As String
Dim I As Long
strCB = ClipBoard_GetData()
I = InStr(strCB, vbCrLf)
If I < Len(strCB) Then
ClipBoard_SetData (Mid(strCB, I + 2))
Else
MsgBox "Keine Headerzeile gefunden"
End If
End Function

'end of code snipplet

HTH
Henry
--
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
Loading...