Advertisement
Guest User

Untitled

a guest
Mar 23rd, 2025
24
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VisualBasic 12.07 KB | Software | 0 0
  1. 'Basic Script für Zwischensummen in OpenOffice/LibreOffice Tabellen
  2. Option Explicit
  3.  
  4. ' Konstanten
  5. Const LABEL_FUER_ZWSUMME = "Zwischensumme: "
  6. Const LABEL_FUER_UEBERTRAG = "Übertrag von vorheriger Seite:"
  7. Const SUMMEN_SPALTE = "F"  ' Feste Summenspalte F (6. Spalte)
  8. Const SUMMEN_SPALTE_INDEX = 5  ' Index für Spalte F (0-basiert, also 5)
  9. Const MAX_ZEILEN_PRO_SEITE = 20  ' Maximale Anzahl Zeilen pro Seite
  10. Const RESERVE_ZEILEN = 2  ' Anzahl Zeilen vor Seitenende für den Umbruch (-2)
  11.  
  12. Sub Main
  13.     On Error GoTo ErrorHandler
  14.    
  15.     Dim oDoc As Object
  16.     Dim oTables As Object
  17.     Dim oItemTabelle As Object
  18.     Dim oMeinViewCursor As Object
  19.    
  20.     oDoc = ThisComponent
  21.     If IsNull(oDoc) Then
  22.         MsgBox "Kein aktives Dokument gefunden.", 16
  23.         Exit Sub
  24.     End If
  25.    
  26.     oTables = oDoc.getTextTables()
  27.     If Not oTables.hasByName("Table_Items") Then
  28.         MsgBox "Die Tabelle 'Table_Items' wurde nicht gefunden.", 16
  29.         Exit Sub
  30.     End If
  31.    
  32.     oItemTabelle = oTables.getByName("Table_Items")
  33.     oMeinViewCursor = oDoc.getCurrentController().getViewCursor()
  34.    
  35.     If IstDokumentMehrseitig(oDoc) Then
  36.         If IstTabelleMehrseitig(oItemTabelle, oMeinViewCursor) Then
  37.             BearbeiteTabelle oDoc, oItemTabelle, oMeinViewCursor
  38.         End If
  39.     End If
  40.     Exit Sub
  41.    
  42. ErrorHandler:
  43.     MsgBox "Ein Fehler ist aufgetreten: " & Err.Description, 16
  44.     Exit Sub
  45. End Sub
  46.  
  47. Sub BearbeiteTabelle(oDoc As Object, oItemTabelle As Object, oMeinViewCursor As Object)
  48.     Dim letzteSpalte As Long
  49.     Dim letzteSpalteAlsIndex As Long
  50.     Dim letzteSpalteAlsBuchst As String
  51.     Dim oTabellenZeilen As Object
  52.     Dim letzteZeile As Long
  53.    
  54.     letzteSpalte = oItemTabelle.getColumns().getCount()
  55.     letzteSpalteAlsIndex = letzteSpalte - 1
  56.     letzteSpalteAlsBuchst = Chr(letzteSpalteAlsIndex + 65)
  57.     oTabellenZeilen = oItemTabelle.getRows()
  58.     letzteZeile = oTabellenZeilen.getCount()
  59.    
  60.     Dim kopfzeilen As Long
  61.     Dim ersteDatenZeile As Long
  62.     kopfzeilen = oItemTabelle.HeaderRowCount
  63.     ersteDatenZeile = kopfzeilen + 1
  64.  
  65.     ' Locale mit Language und Country initialisieren
  66.    Dim aLocale As New com.sun.star.lang.Locale
  67.     aLocale.Language = "de"
  68.     aLocale.Country = "DE"
  69.    
  70.     Dim oAlleZahlenFormate As Object
  71.     Dim formatCode As String
  72.     Dim formatNummer As Long
  73.    
  74.     oAlleZahlenFormate = oDoc.getNumberFormats()
  75.     formatCode = "#.##0,00"  ' Deutsches Zahlenformat
  76.    formatNummer = oAlleZahlenFormate.queryKey(formatCode, aLocale, True)
  77.     If formatNummer = -1 Then
  78.         formatNummer = oAlleZahlenFormate.addNew(formatCode, aLocale)
  79.     End If
  80.  
  81.     ' Berechne dynamische Umbruchzeile mit Reserve
  82.    Dim dynamischeUmbruchzeile As Long
  83.     dynamischeUmbruchzeile = BerechneDynamischeUmbruchzeile(oItemTabelle, ersteDatenZeile)
  84.    
  85.     ' Füge Summenzeile ein und schneide Tabelle ab
  86.    SummenzeileEinfuegen oDoc, oItemTabelle, oMeinViewCursor, dynamischeUmbruchzeile, _
  87.                        ersteDatenZeile, SUMMEN_SPALTE, SUMMEN_SPALTE_INDEX, formatNummer
  88.    
  89.     ' Erstelle neue Tabelle mit Übertragszeile und Restdaten
  90.    ErstelleFortsetzungstabelle oDoc, oItemTabelle, dynamischeUmbruchzeile, _
  91.                               formatNummer, SUMMEN_SPALTE, SUMMEN_SPALTE_INDEX
  92. End Sub
  93.  
  94. Function IstDokumentMehrseitig(oDoc As Object) As Boolean
  95.     IstDokumentMehrseitig = oDoc.getCurrentController().PageCount > 1
  96. End Function
  97.  
  98. Function IstTabelleMehrseitig(oItemTabelle As Object, oMeinViewCursor As Object) As Boolean
  99.     On Error GoTo ErrorHandler
  100.    
  101.     Dim oErsteZelle As Object
  102.     Dim anfangsSeite As Long
  103.     Dim endeSeite As Long
  104.     Dim oOriginalRange As Object
  105.    
  106.     ' Speichere aktuelle Cursor-Position
  107.    oOriginalRange = oMeinViewCursor.getStart()
  108.    
  109.     ' Prüfe ob die Tabelle überhaupt Zellen hat
  110.    If oItemTabelle.Rows.Count < 1 Then
  111.         IstTabelleMehrseitig = False
  112.         Exit Function
  113.     End If
  114.    
  115.     oErsteZelle = oItemTabelle.getCellByName("A1")
  116.     If IsNull(oErsteZelle) Then
  117.         IstTabelleMehrseitig = False
  118.         Exit Function
  119.     End If
  120.    
  121.     ' Gehe zur ersten Zelle
  122.    oMeinViewCursor.gotoRange(oErsteZelle.getAnchor(), False)
  123.     anfangsSeite = oMeinViewCursor.getPage()
  124.    
  125.     ' Gehe zur letzten Zelle der Tabelle
  126.    oErsteZelle = oItemTabelle.getCellByPosition(0, oItemTabelle.Rows.Count - 1)
  127.     oMeinViewCursor.gotoRange(oErsteZelle.getAnchor(), False)
  128.     endeSeite = oMeinViewCursor.getPage()
  129.    
  130.     ' Stelle ursprüngliche Position wieder her
  131.    oMeinViewCursor.gotoRange(oOriginalRange, False)
  132.    
  133.     IstTabelleMehrseitig = (endeSeite > anfangsSeite)
  134.     Exit Function
  135.    
  136. ErrorHandler:
  137.     On Error Resume Next
  138.     ' Versuche zur Original-Position zurückzukehren
  139.    If Not IsNull(oOriginalRange) Then
  140.         oMeinViewCursor.gotoRange(oOriginalRange, False)
  141.     End If
  142.     IstTabelleMehrseitig = False
  143. End Function
  144.  
  145. Function BerechneDynamischeUmbruchzeile(oItemTabelle As Object, ersteDatenZeile As Long) As Long
  146.     Dim oRows As Object
  147.     Dim zeilenAnzahl As Long
  148.     Dim kopfzeilen As Long
  149.     Dim umbruchZeile As Long
  150.    
  151.     oRows = oItemTabelle.getRows()
  152.     zeilenAnzahl = oRows.getCount()
  153.     kopfzeilen = oItemTabelle.HeaderRowCount
  154.    
  155.     ' Berechne die Umbruchzeile:
  156.    ' Bei kleinen Tabellen: die Hälfte der Tabelle
  157.    ' Bei großen Tabellen: MaxZeilenProSeite - ReserveZeilen
  158.    If zeilenAnzahl <= MAX_ZEILEN_PRO_SEITE Then
  159.         umbruchZeile = zeilenAnzahl \ 2
  160.     Else
  161.         umbruchZeile = MAX_ZEILEN_PRO_SEITE - RESERVE_ZEILEN
  162.     End If
  163.    
  164.     ' Stelle sicher, dass die Umbruchzeile nach den Kopfzeilen liegt
  165.    If umbruchZeile <= kopfzeilen Then
  166.         umbruchZeile = kopfzeilen + 1
  167.     End If
  168.    
  169.     BerechneDynamischeUmbruchzeile = umbruchZeile
  170. End Function
  171.  
  172. Sub SummenzeileEinfuegen(oDoc As Object, oItemTabelle As Object, oMeinViewCursor As Object, _
  173.                         umbruchZeile As Long, ersteDatenZeile As Long, _
  174.                         summenSpalte As String, summenSpalteIndex As Long, formatNummer As Long)
  175.     On Error GoTo ErrorHandler
  176.    
  177.     Dim oTabellenZeilen As Object
  178.     Dim oTextCursor As Object
  179.     Dim summenFormel As String
  180.     Dim oCell As Object
  181.     Dim oText As Object
  182.     Dim oCursor As Object
  183.     Dim oTextContent As Object
  184.     Dim oRange As Object
  185.    
  186.     oTabellenZeilen = oItemTabelle.getRows()
  187.    
  188.     ' Füge Zeile an der dynamischen Position ein
  189.    oTabellenZeilen.insertByIndex(umbruchZeile, 1)
  190.    
  191.     ' Setze die Übertragsbeschriftung
  192.    oItemTabelle.getCellByPosition(1, umbruchZeile).setString(LABEL_FUER_ZWSUMME)
  193.    
  194.     ' Formatierung für die Zwischensumme
  195.    oTextCursor = oItemTabelle.createCursorByCellName("B" & (umbruchZeile + 1))
  196.     oTextCursor.CharWeight = com.sun.star.awt.FontWeight.BOLD
  197.     oTextCursor.CharPosture = com.sun.star.awt.FontSlant.ITALIC
  198.     oTextCursor.ParaAdjust = com.sun.star.style.ParagraphAdjust.RIGHT
  199.    
  200.     ' Erstelle die Summenformel (korrigierte Syntax)
  201.    summenFormel = "=SUM(" & summenSpalte & ersteDatenZeile & ":" & summenSpalte & umbruchZeile & ")"
  202.    
  203.     ' Setze die Summenformel in die Zelle
  204.    oCell = oItemTabelle.getCellByPosition(summenSpalteIndex, umbruchZeile)
  205.     oCell.setFormula(summenFormel)
  206.     oCell.NumberFormat = formatNummer
  207.    
  208.     ' Entferne alle restlichen Zeilen nach der Summenzeile
  209.    EntferneRestzeilen oItemTabelle, umbruchZeile
  210.    
  211.     ' Erzwinge einen Seitenumbruch nach dieser Tabelle
  212.    oText = oDoc.getText()
  213.     oCursor = oText.createTextCursor()
  214.    
  215.     ' Gehe zur Position direkt nach der Tabelle
  216.    oTextContent = oItemTabelle
  217.     oRange = oTextContent.getAnchor()
  218.     oCursor.gotoRange(oRange.getEnd(), False)
  219.    
  220.     ' Füge einen Absatz und einen harten Seitenumbruch ein
  221.    oText.insertControlCharacter(oCursor, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK)
  222.     oText.insertControlCharacter(oCursor, com.sun.star.text.ControlCharacter.HARD_PAGE_BREAK)
  223.     Exit Sub
  224.    
  225. ErrorHandler:
  226.     MsgBox "Fehler beim Einfügen der Summenzeile: " & Err.Description, 16
  227.     Exit Sub
  228. End Sub
  229.  
  230. Sub EntferneRestzeilen(oItemTabelle As Object, umbruchZeile As Long)
  231.     Dim oRows As Object
  232.     Dim zeilenAnzahl As Long
  233.     Dim i As Long
  234.    
  235.     oRows = oItemTabelle.getRows()
  236.     zeilenAnzahl = oRows.getCount()
  237.    
  238.     ' Die Zeilen von unten nach oben löschen, damit die Indizes stimmen
  239.    For i = zeilenAnzahl - 1 To umbruchZeile + 1 Step -1
  240.         oRows.removeByIndex(i, 1)
  241.     Next i
  242. End Sub
  243.  
  244. Sub ErstelleFortsetzungstabelle(oDoc As Object, oItemTabelle As Object, umbruchZeile As Long, _
  245.                                formatNummer As Long, summenSpalte As String, summenSpalteIndex As Long)
  246.     Dim oText As Object
  247.     Dim oCursor As Object
  248.     Dim neueTabName As String
  249.     Dim oTables As Object
  250.     Dim spaltenAnzahl As Long
  251.     Dim oNeueTabelle As Object
  252.    
  253.     oText = oDoc.getText()
  254.     oCursor = oText.createTextCursor()
  255.    
  256.     ' Gehe ans Ende des Dokuments
  257.    oCursor.gotoEnd(False)
  258.    
  259.     ' Erzeuge Zeilenumbruch vor der neuen Tabelle
  260.    oText.insertControlCharacter(oCursor, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK)
  261.    
  262.     ' Erstelle eindeutigen Namen für die neue Tabelle
  263.    neueTabName = "Table_Items_Continued"
  264.    
  265.     oTables = oDoc.getTextTables()
  266.    
  267.     ' Lösche alte Fortsetzungstabelle, falls vorhanden
  268.    If oTables.hasByName(neueTabName) Then
  269.         oText.removeTextContent(oTables.getByName(neueTabName))
  270.     End If
  271.    
  272.     ' Ermittle die Anzahl der Spalten in der Originaltabelle
  273.    spaltenAnzahl = oItemTabelle.getColumns().getCount()
  274.    
  275.     ' Erstelle neue Tabelle mit Kopfzeile und Übertragszeile
  276.    oNeueTabelle = oDoc.createInstance("com.sun.star.text.TextTable")
  277.     oNeueTabelle.initialize(2, spaltenAnzahl)
  278.    
  279.     ' Füge die Tabelle ins Dokument ein
  280.    oText.insertTextContent(oCursor, oNeueTabelle, False)
  281.    
  282.     ' Benenne die Tabelle
  283.    oNeueTabelle.setName(neueTabName)
  284.    
  285.     ' Kopiere Kopfzeile
  286.    If oItemTabelle.HeaderRowCount > 0 Then
  287.         KopiereKopfzeile oItemTabelle, oNeueTabelle, spaltenAnzahl
  288.     End If
  289.    
  290.     ' Füge Übertragszeile hinzu
  291.    FuegeUebertragszeileHinzu oNeueTabelle, umbruchZeile, formatNummer, summenSpalte, summenSpalteIndex
  292.    
  293.     ' Übernehme Spaltenbreiten
  294.    UebernehmeSpaltentbreiten oItemTabelle, oNeueTabelle
  295. End Sub
  296.  
  297. Sub KopiereKopfzeile(oItemTabelle As Object, oNeueTabelle As Object, spaltenAnzahl As Long)
  298.     Dim i As Long
  299.     Dim headerText As String
  300.    
  301.     For i = 0 To spaltenAnzahl - 1
  302.         headerText = oItemTabelle.getCellByPosition(i, 0).getString()
  303.         oNeueTabelle.getCellByPosition(i, 0).setString(headerText)
  304.     Next i
  305.    
  306.     oNeueTabelle.HeaderRowCount = 1
  307.     oNeueTabelle.RepeatHeadline = True
  308. End Sub
  309.  
  310. Sub FuegeUebertragszeileHinzu(oNeueTabelle As Object, umbruchZeile As Long, _
  311.                              formatNummer As Long, summenSpalte As String, summenSpalteIndex As Long)
  312.     Dim oTextCursor As Object
  313.     Dim oZelle As Object
  314.    
  315.     oNeueTabelle.getCellByPosition(1, 1).setString(LABEL_FUER_UEBERTRAG)
  316.    
  317.     ' Formatierung für die Übertragsbeschriftung
  318.    oTextCursor = oNeueTabelle.createCursorByCellName("B2")
  319.     oTextCursor.CharWeight = com.sun.star.awt.FontWeight.BOLD
  320.     oTextCursor.CharPosture = com.sun.star.awt.FontSlant.ITALIC
  321.    
  322.     ' Formel für den Übertragswert
  323.    oZelle = oNeueTabelle.getCellByPosition(summenSpalteIndex, 1)
  324.     oZelle.setFormula("=" & summenSpalte & (umbruchZeile + 1))
  325.     oZelle.NumberFormat = formatNummer
  326. End Sub
  327.  
  328. Sub UebernehmeSpaltentbreiten(oOriginalTabelle As Object, oNeueTabelle As Object)
  329.     On Error Resume Next
  330.    
  331.     Dim spaltenAnzahl As Long
  332.     Dim i As Long
  333.     Dim breite As Long
  334.    
  335.     spaltenAnzahl = oOriginalTabelle.getColumns().getCount()
  336.     oNeueTabelle.Width = oOriginalTabelle.Width
  337.    
  338.     For i = 0 To spaltenAnzahl - 1
  339.         breite = oOriginalTabelle.getColumns().getByIndex(i).Width
  340.         If breite > 0 Then
  341.             oNeueTabelle.getColumns().getByIndex(i).Width = breite
  342.         End If
  343.     Next i
  344. End Sub
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement