Hallo zusammen,
ich habe auch mein Archiv aus ELOoffice 11 zu Paperless NGX migriert. Bei mir handelte es sich um ca. 10.000 TIF und PDF-Dokumente
Dabei bin ich wie folgt vorgegangen:
- Ich habe mir alle Dokumente aus dem ELOoffice Archiv in das Filesystem exportiert. Die Ordnerstruktur im ELOoffice wurde zur Verzeichnisstruktur. Den Dateinamen der exportierten Dokumente habe ich wie folgt formatiert: “DATUM”_Titel.”Dateinamenerweiterung”
- Diesen Ordner habe ich dann in Paperless NGX importiert. Dabei habe ich die Ordnernamen als Tags übernommen, das Datum aus dem Dateinamen als “Ausstellungsdatum”, den Titel als “Titel”, den Namen des Originals als “Media Dateinamen”.
Nun zu den Details:
Den Export aus dem ELOoffice habe ich mittels einem ELO-Skript gemacht, welches ich in einem Blog-Beitrag zum ELOoffice gefunden habe.
Dieses habe ich nach meinen Wünschen angepasst. Das einzige Problem waren Zeichen im Titel, die man nicht in einem Dateinamen verwenden konnte. Diese habe ich beim Export durch zwei aufeinanderfolgende Zeichen ersetzt, welche ich beim Import ins Paperless NGX wieder zurückverwandelt habe.
Da ich die Dokumente in ein Filesystem auf dem Mac exportiert habe, störten mich nur folgende Zeichen:
Der Doppelpunkt “:”=> ersetzt durch @1
Der Slash “/” => ersetzt durch @2
Beim Import im Paperless NGX habe ich ein PostConsumption Script verwendet, welches mir das “Ausstellungsdatum”, den “Titel” und den “Media Dateinamen” aus dem Dateinamen im Filesystem herausgelesen hat und auch die ersetzten Zeichen @1 und @2 wieder in die ursprünglichen Zeichen zurückübersetzt hat.
Ehrlich gesagt verwende ich die Ordnerstruktur immer nach als consume Ordner. Dies führt dazu, dass ich immer noch die alte Ordner-Struktur automatisch als Tag beim Importieren zugewiesen bekomme.
Die Zuordnung zu Korrespondenten und zu Ablagepfaden habe ich nach dem Import manuell gemacht.
Das geht relativ schnell, da man ja mittels Tags filtern kann und dann allen markierten Dokumenten einen Korrespondenten und/oder Ablagepfad zuordnen kann.
Anbei das angepasste ELO-Skript zum kompletten Export.
Hinweis:
Dieses Skript habe ich nicht selbst erstellt. Ich habe eine Vorlage aus dem Internet verwendet und es meinen Bedürfnissen angepasst!
Ihr müsst nur das Zielverzeichnis unter DestinationBase anpassen. Darin wird ein Ordner mit dem Namen CS.”YearFrom”-”YearTo” angelegt.
' Skript: DokumentenExport mit Eingabe Jahresbereich
' Autor: XXX
' Erstellt: 15.06.2010
' Letzte Änderung: 12.08.2022
'
' Dieses Skript läuft mittels der Klasse ScriptWalk
' Über alle Nachfolger eines Starteintrags und kopiert
' die Archivstruktur ins Dateisystem.
' Zur Fehlersuche:
'Dim Msg
'Msg = YearFrom & "#" & YearTo
'MsgBox Msg
Option Explicit
Const DestinationBase = "T:\ELO-Export"
Const MaxFolder = 32
Const ArchiveStartNode = 9999
Dim Callback, ELO, Exporter, FSO, StartId, Wait, YearFrom, YearSwap, YearTo
YearFrom = InputBox( "Jahr von" )
YearTo = InputBox( "Jahr bis" )
If YearFrom = "" Then YearFrom = "1900"
If YearTo = "" Then YearTo = "2100"
If YearTo < YearFrom Then
YearSwap = YearTo
YearTo = YearFrom
YearFrom = YearSwap
End If
Set ELO = CreateObject("ELO.office")
Set FSO = CreateObject("Scripting.FileSystemObject")
StartId = ELO.GetEntryId(-1)
If StartId = 0 Then StartId = 1
If StartId > 0 Then
Set Wait = New ExplorerWaitBar
Call Wait.Show("Dokumentenexport", "Starte Export Vorgang")
Set Callback = GetRef("ScriptWalk_Process")
Set Exporter = new ScriptWalk
Call Exporter.Walk(StartId, MaxFolder, Callback)
Call ELO.Status("")
Call Wait.Hide("Export abgeschlossen", 1000)
End If
'''''''''''''''''''''''''''''''''''''''''''''''
' Unterprogramme
'''''''''''''''''''''''''''''''''''''''''''''''
Sub ScriptWalk_Process
Dim Year
Exporter.LevelName = PrepareFilePath(Exporter.LevelName)
Call ELO.Status(Exporter.LevelName)
Call Wait.Update(Exporter.LevelName)
If (ELO.ObjTypeEx < MaxFolder) _
Or (ELO.ObjTypeEx = ArchiveStartNode) Then
CreateFolder
Else
Year = Mid(ELO.ObjXDate, 7, 4)
If Year >= YearFrom _
And Year <= YearTo Then
CopyFile
End If
End If
End Sub
Sub CreateFolder
Dim ActPath, Destination, Name
ActPath = Exporter.GetActPath
If Exporter.LevelName = "CS" Then
Exporter.LevelName = "CS." & YearFrom & "-" & YearTo
End If
Name = LookupFolderName(DestinationBase, ActPath, Exporter.LevelName)
Destination = BuildName(DestinationBase, ActPath, Name, "")
Exporter.LevelName = Name
On Error Resume Next
Call FSO.CreateFolder(Destination)
If Err.Number > 0 Then
call ELO.MsgBox(Err.Number & " " & Err.Description & vbCrLf & Destination, "ELO", vbOkOnly)
End If
End Sub
Sub CopyFile
Dim ActPath, Date, DateInv, Destination, Ext, Name, Name_ori, Retry, Source
Source = ELO.GetDocumentPath(ELO.GetEntryId(-2), 0)
If Source <> "" Then
Ext = ELO.SplitFileName(Source, 3)
Ext = LCase(Ext)
ActPath = Exporter.GetActPath
Date = ELO.ObjXDate
DateInv = Mid(Date, 7, 4) & "-" & Mid(Date, 4, 2) & "-" & Mid(Date, 1, 2)
Name = DateInv & " " & LookupFileName(DestinationBase, ActPath, Exporter.LevelName, Ext)
Destination = BuildName(DestinationBase, ActPath, Name, Ext)
Retry = 1
Name_ori = Name
While FSO.FileExists(Destination)
Name = Name_ori & " (" & Retry & ")"
Destination = BuildName(DestinationBase, ActPath, Name, Ext)
Retry = Retry + 1
Wend
Exporter.LevelName = Name
On Error Resume Next
Call FSO.CopyFile(Source, Destination)
If Err.Number > 0 Then
call ELO.MsgBox(Err.Number & " " & Err.Description & vbCrLf & Destination, "ELO", vbOkOnly)
End If
End If
End Sub
Function LookupFolderName(Base, ActPath, FolderName)
Dim Destination, FolderName_ori, Name, Retry
Destination = BuildName(Base, ActPath, FolderName, "")
FolderName_ori = FolderName
Retry = 1
While FSO.FolderExists(Destination)
FolderName = FolderName_ori & "(" & Retry & ")"
Destination = BuildName(Base, ActPath, FolderName, "")
Retry = Retry + 1
Wend
ELO.DebugOut("New Folder: " & Destination)
ELO.DebugOut("New Name: " & FolderName)
LookupFolderName = FolderName
End Function
Function LookupFileName(Base, ActPath, FileName, Ext)
Dim Destination, Name, Retry
Destination = BuildName(Base, ActPath, FileName, Ext)
Retry = 1
Name = FileName
While FSO.FileExists(Destination)
FileName = Name & "(" & Retry & ")"
Destination = BuildName(Base, ActPath, FileName, Ext)
Retry = Retry + 1
Wend
ELO.DebugOut("New File: " & Destination)
LookupFileName = FileName
End Function
Function BuildName(Base, Path, Name, Ext)
BuildName = Base & Path & "\" & Name & Ext
End Function
Function PrepareFilePath(FilePath)
Dim Reg
Set Reg = New RegExp
Reg.Global = True
' Reg.Pattern = "[*:/?<>|\t\r\n]"
' Reg.Pattern = "[\:\/\n<>\?\"]"
Reg.Pattern = "[/]"
PrepareFilePath = Reg.Replace(FilePath, "@1")
Reg.Pattern = "[:]"
PrepareFilePath = Reg.Replace(PrepareFilePath, "@2")
End Function
'''''''''''''''''''''''''''''''''''''''''''''''
' Klassen
'''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''
' ScriptWalk
'''''''''''''''''''''''''''''''''''''''''''''''
Class ScriptWalk
Private ActPath
Private Level
Private LocalMaxLevel
Private M_LevelName
Private ProcessFunction
Public Sub Walk(StartId, MaxLevel, Callback)
Level = 0
ActPath = ""
LocalMaxLevel = MaxLevel
Set ProcessFunction = Callback
Call LocalWalk(StartId)
End Sub
Public Function GetActPath
GetActPath = ActPath
End Function
Public Property Get LevelName
LevelName = M_LevelName
End Property
Public Property Let LevelName(NewName)
M_LevelName = NewName
End Property
Private Sub LocalWalk(StartId)
Dim ChildList, ChildListString, i, Msg, OldPath
' Zuerst den Eintrag selber einlesen und prüfen
If ELO.PrepareObjectEx(StartId, 0, 0) < 0 Then
' Der Eintrag konnte nicht gelesen werden, hier abbrechen
Exit Sub
End If
M_LevelName = ELO.ObjShort
Call ProcessFunction
' Nun die Nachfolgerliste prüfen. Nur Ordner haben Nachfolger
If ( (ELO.ObjTypeEx <= MaxFolder) _
Or (ELO.ObjTypeEx = 9999)) _
And (Level < LocalMaxLevel) Then
ChildListString = ELO.CollectChildList(StartId)
If ChildListString <> "" Then
ChildList = Split(ChildListString, ":")
Level = Level + 1
OldPath = ActPath
ActPath = ActPath & "\" & M_LevelName
For i = 0 to UBound(ChildList)
If ChildList(i) <> "" Then
Call LocalWalk(ChildList(i))
End If
Next
Level = Level - 1
ActPath = OldPath
End If
End If
End Sub
End Class
'''''''''''''''''''''''''''''''''''''''''''''''
' ExplorerWaitBar
'''''''''''''''''''''''''''''''''''''''''''''''
' Hier beginnt der Funktionsbereich für die Klasse der Statusanzeige
' Die Statusanzeige wird durch Methodenaufrufe in folgender Reihenfolge
' verwendet
'
' Show
' mehrfaches Update
' Hide
Class ExplorerWaitBar
Private Explorer
Public Sub Show(Titel, StartMessage)
Set Explorer = CreateObject("InternetExplorer.Application")
Explorer.Navigate "about:blank"
Explorer.ToolBar = 0
Explorer.StatusBar = 0
Explorer.Left = 400
Explorer.Top = 300
Explorer.Width = 370
Explorer.Height = 160
Do While (Explorer.Busy)
call ELO.Sleep(0, 200)
Loop
Explorer.Visible = 1
call PrepareHtml(Titel, StartMessage)
End Sub
Public Sub Update(Message)
Dim Div, Doc
Set Doc = Explorer.Document
Set Div = Doc.getElementById("msg")
Div.innerHTML = Message
End Sub
Public Sub Hide(ReadyMessage, ShowDelay)
Explorer.Document.Body.InnerHTML = ReadyMessage
call ELO.Sleep(0, ShowDelay)
Explorer.Quit
End Sub
Private Sub PrepareHtml(Title, StartMessage)
Dim Hdr, Body, Start, Doc
Hdr ="<head><title>" & Title & "</title>" & _
"<script type=""text/javascript"">" & _
"var leftpos = 0;" & _
"var innerpos = 0;" & _
"var direction = 1;" & _
"function tick() {" & _
" var outer = document.getElementById(""outer"");" & _
" var inner = document.getElementById(""inner"");" & _
" if (inner && outer) {" & _
" if (direction == 1) {" & _
" if (innerpos < 72) {" & _
" innerpos++;" & _
" inner.style.left = innerpos + ""px"";" & _
" } else {" & _
" leftpos++;" & _
" outer.style.left = leftpos + ""px"";" & _
" if (leftpos > 120) {" & _
" direction = -1;" & _
" }" & _
" }" & _
" } else {" & _
" if (innerpos > 0) {" & _
" innerpos--;" & _
" inner.style.left = innerpos + ""px"";" & _
" } else {" & _
" leftpos--;" & _
" outer.style.left = leftpos + ""px"";" & _
" if (leftpos < 1) {" & _
" direction = 1;" & _
" }" & _
" }" & _
" }" & _
"}" & _
"}" & _
"</script></head>"
Body = "<body scroll=""no"" onload=""setInterval('tick()', 20);"">" & _
"<div style=""border:solid 1px;width:203px;color:#808080"">" & _
"<div id=""outer"" style=""position:relative;left:0px;" & _
"width:80px;background-color:#f0f0fa;height:30px"">" & _
"<div id=""inner"" style=""position:relative;left:0px;width:8px;" & _
"background-color:#00ff80;height:30px"">" & _
"<div style=""position:relative;left:0px;width:4px;" & _
"background-color:#ffc840;height:30px"">" & _
" </div></div></div></div><div id=""msg"">" & _
StartMessage & "</div></body>"
Start = "<html>" & Hdr & Body & "</html>"
Set Doc = Explorer.Document
Doc.Open
Call Doc.Write(Start)
Doc.Close
End Sub
End Class
Falls Interesse besteht, kann ich auch noch den Import in Paperless NGX genauer beschreiben.