İşte farklı bir yaklaşım. Kullanarak sayfa sonlarını belirlemenin bir yolu olup olmadığını merak ettim. IsStartOfNewPage
. Bu, LO Calc'ı Sayfa Sonu Görünümü'ne ve geriye doğru geçiş yaparak sayfa sonlarını hesaplayarak yapar. Şimdi, sayfaları saymak, kullanılan tüm hücreleri (geçerli sayfanın sayfasını kullanarak) yineleyerek oldukça kolaydır. Cursor
ve GotoEndOfUsedArea
).
Birden fazla sayfayı kapsayan hücrelerin yanlış sayfa sayımına yol açıp açmayacağını test etmedim. Ayrıca, ortaya çıkan ToC’nin asla birden fazla sayfa almayacağını tahmin ediyorum.
Option Base 0
Option Explicit
Private Type SheetInformation
SheetIndex As Long
SheetName As String
PageStart as Long
PageEnd as Long
PageCount As Long
End Type
Public Sub Calc_ToC
If (False = IsSpreadsheetDoc(ThisComponent)) Then
MsgBox "Works only for spreadsheets!"
Exit Sub
End If
ThisComponent.LockControllers
Dim mySheets(ThisComponent.Sheets.getCount() - 1) As New SheetInformation
Dim origSheet As Long
origSheet = ThisComponent.getCurrentController.ActiveSheet.RangeAddress.Sheet
Call collectSheetInfo(mySheets)
dim document as Object
dim dispatcher as Object
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Nr"
args1(0).Value = origSheet + 1
dispatcher.executeDispatch(document, ".uno:JumpToTable", "", 0, args1())
ThisComponent.unlockControllers()
Call insertToc(mySheets)
End Sub
Private Sub collectSheetInfo(allSheetsInfo() as New SheetInformation)
Dim i As Long
Dim maxPage As Long
maxPage = 0
For i = 0 To UBound(allSheetsInfo)
Dim sheetInfo As New SheetInformation
sheetInfo.SheetIndex = i
sheetInfo.SheetName = ThisComponent.Sheets.getByIndex(sheetInfo.SheetIndex).getName()
Call getPageCount(sheetInfo)
sheetInfo.PageStart = maxPage + 1
sheetInfo.PageEnd = sheetInfo.PageStart + sheetInfo.PageCount - 1
maxPage = sheetInfo.PageEnd
allSheetsInfo(i) = sheetInfo
Next
End Sub
Private Sub getPageCount(s As SheetInformation)
Dim oSheet, oCell, oCursor As Object
Dim i, j, pageCount As Long
Dim isHorizontalPageBreak, isVerticalPageBreak As Boolean
dim document as Object
dim dispatcher as Object
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Nr"
args1(0).Value = s.SheetIndex + 1
dispatcher.executeDispatch(document, ".uno:JumpToTable", "", 0, args1())
args1(0).Name = "PagebreakMode"
args1(0).Value = true
dispatcher.executeDispatch(document, ".uno:PagebreakMode", "", 0, args1())
dim args2(0) as new com.sun.star.beans.PropertyValue
args2(0).Name = "NormalViewMode"
args2(0).Value = true
dispatcher.executeDispatch(document, ".uno:NormalViewMode", "", 0, args2())
oSheet = ThisComponent.Sheets.getByIndex(s.SheetIndex)
oCursor = oSheet.createCursor
oCursor.GotoEndOfUsedArea(True)
pageCount = 1
For i=0 To oCursor.RangeAddress.EndColumn
For j=0 To oCursor.RangeAddress.EndRow
oCell = oSheet.GetCellByPosition(i,j)
isHorizontalPageBreak = Abs(cINT(oCell.Rows.getByIndex(0).IsStartOfNewPage))
isVerticalPageBreak = Abs(cINT(oCell.Columns.getByIndex(0).IsStartOfNewPage))
If i = 0 Then
If isHorizontalPageBreak Then
pageCount = pageCount + 1
End If
ElseIf j = 0 Then
If isVerticalPageBreak Then
pageCount = pageCount + 1
End If
Else
If (isHorizontalPageBreak AND isVerticalPageBreak) Then
pageCount = pageCount + 1
End if
End if
Next j
Next i
s.pageCount = pageCount
End Sub
''' -------------------------------------------------------------
''' IsSpreadsheetDoc - Check if current document is a calc file
''' -------------------------------------------------------------
''' Source: "Useful Macro Information For OpenOffice.org By
''' Andrew Pitonyak", Ch. 6.1
''' -------------------------------------------------------------
Private Function IsSpreadsheetDoc(oDoc) As Boolean
Dim s$ : s$ = "com.sun.star.sheet.SpreadsheetDocument"
On Local Error GoTo NODOCUMENTTYPE
IsSpreadsheetDoc = oDoc.SupportsService(s$)
NODOCUMENTTYPE:
If Err <> 0 Then
IsSpreadsheetDoc = False
Resume GOON
GOON:
End If
End Function
Private Sub Result(s() As SheetInformation)
Dim msg As String
Dim i As Integer
Dim obj As SheetInformation
msg = ""
For i = 0 To UBound(s)
obj = s(i)
With obj
msg = msg & .SheetName & " (Index: " & .SheetIndex & _
") - Pages: " & .PageCount & _
" - from/to: " & .PageStart & "/" & .PageEnd & CHR(13)
End With
Next
MsgBox(msg)
End Sub
Private Sub insertToC(s() As SheetInformation)
Select Case MsgBox("Insert ToC on cursor position?" & CHR(10) & _
"(Yes: Insert at cursor; No: stop macro)", 36)
Case 6 'Yes - insert at cursor position'
Call DoInsert(s)
Case 7 'No - insert on new sheet'
ThisComponent.unlockControllers()
Exit Sub
End Select
End Sub
Private Sub DoInsert(s() As SheetInformation)
Dim oSheet, oCell, startCell As Object
Dim sheet,rowStart, colStart, row, col, start As Long
Dim sName As String
Dim currentSheet As SheetInformation
Dim newToc As Boolean
oSheet = ThisComponent.getCurrentController.ActiveSheet
startCell = ThisComponent.getCurrentSelection()
oCell = startCell
rowStart = startCell.CellAddress.Row
colStart = startCell.CellAddress.Column
oCell.SetString("Table of Contents")
For sheet = 1 to Ubound(s) + 1
currentSheet = s(sheet - 1)
row = rowStart + sheet
oCell = oSheet.getCellByPosition(colStart, row) ' column B
oCell.SetString(currentSheet.SheetName)
oCell = oSheet.getCellByPosition(colStart + 2, row) ' column D
start = currentSheet.PageStart
oCell.SetString("Page " & start)
Next
ThisComponent.unlockControllers()
End Sub
Andrew Pitonyak tarafından bazı örnek kodlar kullandım (" OpenOffice.org İçin Faydalı Makro Bilgiler Andrew Pitonyak (ODT) tarafından " ve " OpenOffice.org Makrolar Açıklaması (PDF) ") ve tarafından Villeroy'un Hücre inceleme modülü ve tabii ki JimK'nin çözümü .
DÜZENLE:
Makro, yazdırılabilir içerik içeriyorsa her sayfayı test etmez. Basitçe, "kullanılmış" tam hücre aralığının ( GotoEndOfUsedArea
ToC oluşturulurken) dikkate alınmalıdır. Bu nedenle, boş sayfaları yazdırılacak sayfalar olarak sayabilir. Bu nedenle, seyrek dolgulu sayfalar için kötü sonuçlar doğurabilir. Ancak umarım boş sayfa olmayan çoğu durumda daha güvenilir davranır.
Bu nedenle, bir sonraki sayfada (aşağıdaki sayfalar olmasa bile) altı sayfaya yazdırılacak X
) boş kalabilir:
+-+-+ +-+-+ +-+-+
|X|X| |X|X| |X| |
+-+-+ +-+-+ +-+-+
|X| | | |X| | | |
+-+-+ +-+-+ +-+-+
|X|X| |X|X| | |X|
+-+-+ +-+-+ +-+-+