gelöst: Tabellenblatt zwischen Dokumenten kopieren

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

erikafuchs
******
Beiträge: 690
Registriert: Di, 13.02.2007 17:38
Wohnort: Büttelborn

gelöst: Tabellenblatt zwischen Dokumenten kopieren

Beitrag von erikafuchs »

Hallo zusammen,

Mein Projekt, die Schüler unserer Schule im Rechnen weiterzubringen ist schon recht weit gediehen. (Siehe: "Alle Dateien eines Ordners per Makro einlesen" und "Tabellen mit Formatierung übertragen"). Die Schüler unserer Schule müssen (bald alle) jede Woche eine Calc Datei als Wochenaufgabe abgeben. Um die Ergebnisse schneller auswerten zu können soll eine Seite ("Übersicht") aus jeder Schülerdatei ("Rechentrainer_sname.ods") einer Lerngruppe in eine zentrale Datei eingefügt werden. Nach meinen Versuchen stellte sich heraus, dass die Formatierung der "Übersicht"seite nur erhalten bleibt, wenn ich die ganze Seite der einen Datei kopiere und dann in die zentrale Datei einfüge. - Einfügen klappt, Kopieren klappt - aber nicht das Kopieren der Seite aus der einen Datei (InDoc -> InSheets -> InTab) in die andere Datei (oDatei -> oSheets -> oTab). Ich habe das mit dem Befehl "oSheets.copyByName(InTab,sname,oSheets.getcount()-1)" versucht, erhalte aber die Meldung "Falscher Wert für Eigenschaft". Ich habe die Befürchtung, dass man zwischen zwei Dateien keine Tabellenblätter kopieren kann - wer weiss was?

Dank für Hilfe von Pit

Code: Alles auswählen

dim oDoc, oSheets, oTab, InDoc, InSheets, InTab as object
dim vorname, nachname, sname as string 
dim Anzahl as integer
dim aDateien() as string
dim arg()

sub einfuegen
   If ( Not GlobalScope.BasicLibraries.isLibraryLoaded( "Tools" ) ) Then
      GlobalScope.BasicLibraries.LoadLibrary( "Tools" )
   End If

   oDoc=ThisComponent                                                                           'Das zentrale Daokument
   oSheets=oDoc.getSheets(0)

   aDateien = ReadDirectories("f:\Rechentrainer\Hausaufgaben\Mathe_7" , TRUE , FALSE , FALSE )  'Das Verzeichnis mit den Schülerdateien
   If uBound( aDateien ) > -1 then
      Anzahl = uBound( aDateien ) + 1

      for i = lBound( aDateien ) to uBound( aDateien )
         InDoc=StarDesktop.loadComponentFromURL(aDateien(i), "_blank", 0, Arg())                'Öffnen der Schülerdateien
         InTab=InDoc.sheets.getByName("Übersicht")                                              'Die einzufügende Seite aus den Schülerdateien
         nachname=InDoc.sheets.getByName("Daten").getCellByPosition(1,1).string          
         vorname=InDoc.sheets.getByName("Daten").getCellByPosition(2,1).string
         sname=nachname & "_" & vorname                                                         'Der Schülername als Seitenname
  
         oSheets.copyByName(InTab,sname,oSheets.getcount()-1)                                   'Dieser Befehl klappt nicht

         InDoc.close(true)                                                                      'Schließen der Schülerdateien
      next i
   end if
end sub
Zuletzt geändert von erikafuchs am Fr, 16.05.2008 16:09, insgesamt 1-mal geändert.
Benutzeravatar
komma4
********
Beiträge: 5332
Registriert: Mi, 03.05.2006 23:29
Wohnort: Chon Buri Thailand Asia
Kontaktdaten:

Re: Tabellenblatt zwischen Dokumenten kopieren

Beitrag von komma4 »

Pit,

ich habe im DevelopersGuide keine passende Methode gefunden.

In Andrews Makro-Dokument, Kap. 6.18.1 Copy entire sheet to a new document verwendet Stephan dispatcher calls, um "Alles" zum Kopieren zu erwischen.


Code: Alles auswählen

'Author: Stephan Wunderlich [stephan.wunderlich@sun.com] 
Sub CopySpreadsheet
  firstDoc = ThisComponent
  selectSheetByName(firstDoc, "Sheet2")
  dispatchURL(firstDoc,".uno:SelectAll")
  dispatchURL(firstDoc,".uno:Copy")
  secondDoc = StarDesktop.loadComponentFromUrl("private:factory/scalc","_blank",0,dimArray())
  secondDoc.getSheets().insertNewByName("inserted",0)
  selectSheetByName(secondDoc, "inserted")
  dispatchURL(secondDoc,".uno:Paste")
End Sub

Sub selectSheetByName(document, sheetName)
  document.getCurrentController.select(document.getSheets().getByName(sheetName))
End Sub

Sub dispatchURL(document, aURL)
  Dim noProps()
  Dim URL As New com.sun.star.util.URL

  frame = document.getCurrentController().getFrame()
  URL.Complete = aURL
  transf = createUnoService("com.sun.star.util.URLTransformer")
 transf.parseStrict(URL)

  disp = frame.queryDispatch(URL, "", com.sun.star.frame.FrameSearchFlag.SELF _
         OR com.sun.star.frame.FrameSearchFlag.CHILDREN)
  disp.dispatch(URL, noProps())
End Sub
Das solltest Du leicht anpassen können.


Bei dieser Art zu kopieren (es wird die Zwischenablage verwendet) bleiben Format-Definitionen erhalten (ein Absatzformat "Überschrift" bleibt "Überschrift") – wenn ein Schüler Eigenschaften der Formate umdefiniert hat, dann wird das nicht übernommen (=beim Kopieren wird das Format der Zieldatei genommen).
Benutzerdefinierte Formate ("myÜberschrift") werden in die Zieldatei mitkopiert.






Beim Verlinken [wie woanders vorgeschlagen] hast Du Probleme mit rekursiven Referenzen?
D.h.: bei den Schüler-Dateien sind schon Verweise auf Deine Übersicht.ods?
Ist das erforderlich?


Ich bin immer noch der Meinung, dass ein Kopieren von Daten zum Zweck einer Auswertung überflüssig ist.

Beschreibe bitte noch einmal die Aufgabe:
Deine Schüler geben wöchentlich jeweils eine Calc-Datei ab, und Du möchtest bestimmte Zellwerte (auf Übereinstimmung mit erwarteter Antwort?) kontrollieren?


HTH
Cheers
Winfried
aktuell: LO 5.3.5.2 30m0(Build:2) SUSE rpm, unter Linux openSuSE Leap 42.3 x86_64/KDE5
DateTime2 Einfügen von Datum/Zeit/Zeitstempel (als OOo Extension)
erikafuchs
******
Beiträge: 690
Registriert: Di, 13.02.2007 17:38
Wohnort: Büttelborn

Re: Tabellenblatt zwischen Dokumenten kopieren

Beitrag von erikafuchs »

Lieber Winfried,

vielen Dank, da hast du dir ja wieder viel Mühe gegeben. Durch das Makro von Andrews muss ich mich erst durchbeißen - ich fühle mich immer noch als fortgeschrittener Anfänger.
Aber ich versuche dir mal mein Calcdokument genauer zu beschreiben (Ich kann es dir aber auch einfach mal schicken - ich möchte das sowieso öffentlich zugängig machen): Die Schüler öffnen eine .ots Datei, müssen ihren Namen eingeben und speichern das Dokument auf einem USB Stick. Auf mehreren Tabellenseiten befinden sich Buttons, die jeweils ein Dialog starten der jeweils 10 Aufgaben aus allen Bereichen der Mathematik generieren. Jeder richtige und falsche Antwort wird auf einer versteckten Seite gesammelt. Auf einem Übersichtsblatt werden dann tabellarisch alle Aufagbenbereiche mit Anzahl der Aufgaben, Fehlerquote, Bearbeitungszeit, Aufgaben, die jeweils innerhalb einer Woche bearbeitet wurden ... usw. dargestellt. Alle Tabellenseiten sind gesperrt, die Schüler können nur die Makros starten. Jetzt schicken mir die Schüler wöchentlich das ganze Dokument und ich überprüfe, ob sie in jeder Woche mindesten 100 Aufgaben gerechnet haben und sehe wo sie Probleme haben. Bisher muss ich in jeder Lerngruppe 15 bis 25 Dateien öffnen und händisch eine Liste erstellen wer wann was erledigt hat und wo es Probleme gab. Die Übersichtseite besteht nur aus Links zu einer unübersichtlichen, versteckten "Datensammelseite". Ich hätte jetzt gerne ein Dokument, in das alle Schülerübersichtsseiten eingelesen werden (gerne auch als Link) und dann soll in diesem zentarlen Dokument auf einer Seite Durchschnittswerte, auf einer Seite Summen und eben auf einer Seite in einer Tabelle zu erkennen sein was die einzelnen Schüler gemacht haben und was nicht. Schön wäre es halt wenn ich außer diesen drei Seiten auch innerhalb des zentralen Dokuments noch von jedem Schüler direkt seine Übersichtsseite anklicken könnte. Wahrscheinlich hast du recht und Links wären einfacher aber dann bräuchte ich Hilfe, wie ich dafür sorge dass die Verknüpfungen beim Einfügen nicht geändert werden.

PS.
Jeder der an dem Programm interessiert ist kann es gerne haben, ausprobieren, seinen Senf dazugeben und mithelfen! Ich bin davon überzeugt, dass dieses Programm den meisten unserer Schüler helfen würde, da sie alles was vor dem letzten Test lag zu einem großen Teil vergessen. Wir werden wohl auf der nächsten Fachkonferenz in unserer Schule beschließen, dass alle Schüler damit arbeiten müssen.

Vielen Dank für euere Mithilfe
Pit
Benutzeravatar
komma4
********
Beiträge: 5332
Registriert: Mi, 03.05.2006 23:29
Wohnort: Chon Buri Thailand Asia
Kontaktdaten:

Re: Tabellenblatt zwischen Dokumenten kopieren

Beitrag von komma4 »

Ich sehe kein Problem darin die 25 Dateien zu verlinken und die Daten auszuwerten.

Bitte schildere nochmal, wo die Probleme mit den Verknüpfungen (welche>wohin) liegen - und inwieweit sie sich ändern (beim Kopieren auf welche Weise).



Das Szenario stellt sich mir nun so dar:

* eine Anzahl von Calc-Dateien wurde von USB-Sticks auf den Rechner kopiert;
* in jeder Datei (nach bekanntem Namensmuster) gibt es ein Blatt "Übersicht", welches mit Formel und Makros die Werte der Berechnungen sammelte
* in Deiner Lehrerübersicht möchtest Du Schüler-bezogene (und Klassen-Statistik?) Auswertungen?


meine Lösung:

eine Calc-Vorlagen-Datei, mit


Blatt "Klasse"
Spalte A: Schülername
hier wird eine Liste reinkopiert

Blatt "Steuerung"
Zellen, die mit Einfügen>Namen>Festlegen, bspw. den Pfad zu den Dateien definieren (andere Parameter), um damit eine variable Makro-Steuerung zu ermöglichen

Makros:
* zum Erstellen/Ersetzen der Links, Zielname wird ermittelt aus "/verzeichnis/Schülername.ods#Übersicht.A2:A_max" und den Zellwerten der "Steuerung"

Blatt "Auswertung"
Formeln oder benutzerdefinierte Funktionen, welche aus allen verlinkten Schüler-Blättern berechnen...
Das kann evtl. auf den Folge-Spalte der "Klasse" dargestellt werden.


Aus dieser Vorlage kann für jede Klasse/Jahrgang/Fach/Lehrer ein Auswertungs-Dokument erstellt werden.



+
Wenn Du eine Datei irgendwo hochlädst - oder hier anhängst:
bitte von Anfang an versionieren [AufgabenAuswertung-0.1.0.ods], und die Daten natürlich anonymisieren.



Kommen wir weiter?
Cheers
Winfried
aktuell: LO 5.3.5.2 30m0(Build:2) SUSE rpm, unter Linux openSuSE Leap 42.3 x86_64/KDE5
DateTime2 Einfügen von Datum/Zeit/Zeitstempel (als OOo Extension)
erikafuchs
******
Beiträge: 690
Registriert: Di, 13.02.2007 17:38
Wohnort: Büttelborn

Re: Tabellenblatt zwischen Dokumenten kopieren

Beitrag von erikafuchs »

Lieber Winfried,

das mit dem Verlinken habe ich ausprobiert und auch hinbekommen - außer den Verknüpfungen. Ich sage ja, ich habe wahrscheinlich ein Anfängerproblem: Die Seite mit den versteckten Daten ("Daten") ist das erste Tabellenblatt, das sichtbare Übersichtsblatt ("Übersicht") ist das zweite Tabellenblatt. Auf diesem Übersichtblatt sind dann Verknüpfungen der Form "=$Daten.$AA$99" diese müsste ich jetzt wahrscheinlich irgendwie ergänzen um den Namen des Dokuments "Dokument.$Daten.$AA$99"oder so. Da müsste ich wahrscheinlich alle Verknüpfungen um den Namen der jeweiligen Datei ergänzen. Ich habe keine Idee wie diese formuliert werden muss.

Ich habe hier auch noch nie eine Datei hochgeladen, aber ich teste das mal. Ich hätte auch noch eine pdf Datei mit einer Gebrauchsanweisung. Das Passwort für den Makro und Tabellenschutz möchte ich hier nicht bekanntmachen, da das die Schüler natürlich nicht rausbekommen dürfen - gibt es da eine andere Möglichkeit?

Grüße
Pit
Dateianhänge
Rechentrainer 1.58.ots
(126.19 KiB) 58-mal heruntergeladen
erikafuchs
******
Beiträge: 690
Registriert: Di, 13.02.2007 17:38
Wohnort: Büttelborn

Re: Tabellenblatt zwischen Dokumenten kopieren

Beitrag von erikafuchs »

Ach ja, meinen ersten Versuch mit der Übersichtsdatei lade ich dann auch mal hoch. Das Makro hat noch keinen Startknopf und der copy Befehl geht halt nicht.

Grüße
Pit
Dateianhänge
Rechentrainer Datenbank Mathe7.ods
(19.04 KiB) 60-mal heruntergeladen
erikafuchs
******
Beiträge: 690
Registriert: Di, 13.02.2007 17:38
Wohnort: Büttelborn

Re: Tabellenblatt zwischen Dokumenten kopieren

Beitrag von erikafuchs »

Ich habe noch etwas rumprobiert. Die Verknüpfung "='file:///D:/Ordner/Unterordner/Dateiname.ods'#Übersicht.A1"" verliert auch die Formatierung. Was wunderbar funktioniert ist, wenn ich in der Ursprungsdatei die Spalten markiere, in die Zwischenablage kopiere und in der Zieldatei einfüge. (Kopiere ich nur A1:Z99 geht die Spaltenbreite verloren.) Geht das vielleicht auch als Makro? Ach ja, dass ich meine Übersichtsdatei hochgeladen habe ist natürlich recht unnötig, ich hätte ja auch einfach den Code hier einfügen können:

Code: Alles auswählen

dim oDoc, oSheets, oTab, InDoc, InSheets, InTab as object
dim vorname, nachname, sname as string 
dim Anzahl as integer
dim aDateien() as string
dim arg()

sub einfuegen
   If ( Not GlobalScope.BasicLibraries.isLibraryLoaded( "Tools" ) ) Then
      GlobalScope.BasicLibraries.LoadLibrary( "Tools" )
   End If

   oDoc=ThisComponent                                                                           'Das zentrale Dokument
   oSheets=oDoc.getSheets(0)

   aDateien = ReadDirectories("f:\Rechentrainer\Hausaufgaben\Mathe_7" , TRUE , FALSE , FALSE )  'Das Verzeichnis mit den Schülerdateien
   If uBound( aDateien ) > -1 then
      Anzahl = uBound( aDateien ) + 1

      for i = lBound( aDateien ) to uBound( aDateien )
         InDoc=StarDesktop.loadComponentFromURL(aDateien(i), "_blank", 0, Arg())                'Öffnen der Schülerdateien
         InTab=InDoc.sheets.getByName("Übersicht")                                              'Die einzufügende Seite aus den Schülerdateien
         nachname=InDoc.sheets.getByName("Daten").getCellByPosition(1,1).string          
         vorname=InDoc.sheets.getByName("Daten").getCellByPosition(2,1).string
         sname=nachname & "_" & vorname                                                         'Der Schülername als Seitenname
  
         oSheets.copyByName(InTab,sname,oSheets.getcount()-1)                                   'Dieser Befehl klappt nicht

         InDoc.close(true)                                                                      'Schließen der Schülerdateien
      next i
   end if
end sub
[/[/code]

Grüße
Pit
Benutzeravatar
komma4
********
Beiträge: 5332
Registriert: Mi, 03.05.2006 23:29
Wohnort: Chon Buri Thailand Asia
Kontaktdaten:

Re: Tabellenblatt zwischen Dokumenten kopieren

Beitrag von komma4 »

Pit,

was auch funktionieren könnte:

Du kannst doch ein Tabellenblatt durch re.Maustaste auf dem Tabellenreiter kopieren ... in eine andere geöffnete Datei.
Das Aufzeichnen dieser Aktion als Makro ergibt ein Stück dispatcher Code, welches verwendbar scheint (Dateinamen lassen sich parametrisieren).
Damit wird eine 1:1 Kopien eines Blattes erzeugt.

Viel Erfolg!
Cheers
Winfried
aktuell: LO 5.3.5.2 30m0(Build:2) SUSE rpm, unter Linux openSuSE Leap 42.3 x86_64/KDE5
DateTime2 Einfügen von Datum/Zeit/Zeitstempel (als OOo Extension)
erikafuchs
******
Beiträge: 690
Registriert: Di, 13.02.2007 17:38
Wohnort: Büttelborn

Re: Tabellenblatt zwischen Dokumenten kopieren

Beitrag von erikafuchs »

Lieber Wilfried,
vielen Dank mal wieder. Deinen Tip hatte ich auch schon probiert, da klappt immer was anderes nicht. Wenn ich den Bereich kopiere werden die Spaltenbreiten verändert und (wenn ich mich recht erinnere) geht das mit dem dispatcher gar nicht mit verschiedenen Dokumenten. Ich habe jetzt im englischsprachigen Forum was gefunden, muss es aber noch umbauen und testen - ich werde berichten.

Noch eine Bitte: Ich habe gesehen, dass mein Rechentrainer mehrmals runtergeladen wurde. Da ich als Anfänger das ganze Ding mit viel "Trial and Error" zusammengebastelt habe und niemanden kenne, der auch nur Basic programmieren kann, würde mich eure professionellen Kommentare zu meinem Gebastel interessieren. Bitte schreibt mir!

Grüße von Pit
erikafuchs
******
Beiträge: 690
Registriert: Di, 13.02.2007 17:38
Wohnort: Büttelborn

Re: Tabellenblatt zwischen Dokumenten kopieren

Beitrag von erikafuchs »

Wie versprochen: Hier ist eine Lösung:

Code: Alles auswählen

Sub CopySheetfFromOtherDocument 
   Dim oDoc as object   ' 
   Dim mNoArgs() 
   sPath = "file:///f:/Rechentrainer/Hausaufgaben/Mathe_7/" 
   sUrlQuelle = "RechentrainerSchueler.ods" 
   sUrlQuelleoO=ConvertToURL(sPath & sUrlQuelle) 
    
   oDoc=ThisComponent
  
   REM  I use the link sheets. 
  
   mySheetToCopy="='"+sUrlQuelleoO+"'#$Übersicht.A1"          
   oDoc.Sheets.getByName("Ende").getCellByposition(0,0).setFormula(mySheetToCopy) 
   REM   Count Sheets for next process 
   CountSheets=oDoc.getSheets().count    
   REM  make the copy of sheet linked    
      
      for tosheet=1 to CountSheets 
     
         sheetpresent=oDoc.Sheets(tosheet-1).Name 
         if instr(sheetpresent,"file")>0 then 
            REM  forgot the sheet of the link 
            if    oDoc.getSheets().getByName(sheetpresent).IsVisible="False" then    
               oDoc.getSheets().getByName(sheetpresent).IsVisible="True" 
            endif 
            REM make the copy 
            oDoc.Sheets().copyByName(sheetpresent,"Kopie",2)             
            REM  delete the sheet link 
            oDoc.Sheets().removeByName(sheetpresent) 
            exit for 
         endif       
         next tosheet 
         REM   clean the cell A1 
   oDoc.Sheets.getByName("Ende").getCellByposition(0,0).setString("")       
End Sub 
Dieses Programm fügt einen Link auf die Seite "Übersicht" aus der Datei "RechentrainerSchueler" in die Seite "Ende" der geöffneten Datei ein, kopiert diese auf die Seite "Kopie" und löscht anschließend den Link und die Zelle A1 auf der Seite "Ende" wieder.

Ich habe den Code auf der Seite http://www.oooforum.org/forum/viewtopic ... 813#282813 gefunden und etwas angepasst. Warum die "tosheet" Schleife durchlaufen werden muss, ist mir schleierhaft - vielleicht kann mir da jemand weiterhelfen. Ansonsten klappt das soweit und ist schnell!

Wenn jemand wissen will wie es weitergeht - von allen Dateien eines Ordners je eine Seite kopieren, möge das hier mitteilen.

Grüße
Pit
Antworten