Propaganda různých ChatBlbečků mě už otravuje víc než reklama, ale rozhodně palec nahoru za několikadenní samostatnou snahu udělat řešení
.
Zde neproprasená lidská verze.
Do konstanty cInitDir si dejte výchozí adresář kde se vám má otevírat dialog pro výběr CSV.
Hledání položek zohledňuje velikost písmen.
Sub zpracujCSV 'nahradí daty z CSV data v dokumentu
on local error goto bug
const cInitDir="d:\" 'výchozí adresář při výběru souboru (možno file:///.... ale i d:\...)
const cUndo="vložení dat z CSV" 'hláška pro krok Zpět
dim oDoc as object, sUrl$, p(), oDesc as object, p1(), p2(), i&, i1%, i2%, s1$, s2$, undoMgr as object
rem výběr souboru
sUrl=dialogVybratSoubor(cInitDir)
if sUrl="" then exit sub 'nebyl vybrán soubor
p=loadFileString(sUrl) 'pole s řádky souboru
oDoc=ThisComponent
rem odstranit úvodní a koncovou uvozovku z řádků
s1=p(0) : s2=p(1)
s1=Mid(s1, 2, Len(s1)-2) : s2=Mid(s2, 2, Len(s2)-2)
rem dostat jednotlivé položky řádků
p1=split(s1, """,""") : i1=ubound(p1) 'řetězec rozdělit raději dle "," než samotné čárky, neboť někde v těle položky by též mohla být čárka "... , ..."
p2=split(s2, """,""") : i2=ubound(p2)
if i1<>i2 then 'hlavička nemá stejný počet položek jako tělo
msgbox("Hlavička: " & i1 & chr(13) & "Tělo: " & i2, 48, "Různý počet částí")
stop
end if
rem nahradit text v dokumentu
oDoc.lockControllers
undoMgr=oDoc.UndoManager
undoMgr.enterUndoContext(cUndo)
oDesc=oDoc.createReplaceDescriptor
oDesc.SearchCaseSensitive=true 'při nahrazování hledět na velikost písmen
for i=0 to i1
with oDesc
.SearchString=p1(i)
.ReplaceString=p2(i)
end with
oDoc.replaceAll(oDesc)
next i
undoMgr.leaveUndoContext()
oDoc.unlockControllers
exit sub
bug:
if oDoc.hasControllersLocked() then oDoc.unlockControllers()
if undoMgr.getCurrentUndoActionTitle=cUndo then 'byly nějaké změny v dokumentu
with undoMgr
.leaveUndoContext() 'uzavřít UndoManager
.undo() 'vrátit změny
end with
end if
bug(Erl, Err, Error, "zpracujCSV")
End Sub
Function dialogVybratSoubor(optional sInitDir$) as string 'dialog pro vybrání souboru
on local error goto bug
dim oFileDlg as object, oFileAccess as object, oFiles as object, sFile$, bDir as boolean
rem check init directory
if NOT isMissing(sInitDir) then 'je předán výchozí adresář
if FileExists(sInitDir) then bDir=true 'adresář existuje
end if
if bDir=False then sInitDir=CreateUnoService("com.sun.star.util.PathSettings").Work 'výchozí adresář z menu: Nástroje/Možnosti -> LibreOffice/Cesty -> Mé dokumenty
oFileDlg=CreateUnoService("com.sun.star.ui.dialogs.FilePicker")
with oFileDlg 'nastavit viditelné soubory v dialogu
.AppendFilter("Vše (*.*)", "*.*")
.AppendFilter("CSV (*.csv)", "*.csv")
.SetCurrentFilter("CSV (*.csv)") 'výchozí typy souborů
end with
oFileAccess=CreateUnoService("com.sun.star.ucb.SimpleFileAccess")
oFileDlg.SetDisplayDirectory( ConvertToUrl( sInitDir ) )
if oFileDlg.execute() then 'otevřít dialog
oFiles=oFileDlg.getFiles()
if ubound(oFiles)>=0 then
sFile=oFiles(0)
end if
end if
dialogVybratSoubor=sFile
exit function
bug:
bug(Erl, Err, Error, "dialogVybratSoubor")
End Function
Function loadFileString(sUrl$, optional sEncoding$) as variant 'načte soubor do pole (samodetekuje Enter)
on local error goto bug
if isMissing(sEncoding) then sEncoding="UTF-8" 'když není zadáno kódování tak předpokládat utf-8
dim s$, oSfa as object, oTextStream as object, oStream as object, sEnter$, sLine$, aBytes(1) as byte, iLine&
oSfa=CreateUNOService("com.sun.star.ucb.SimpleFileAccess")
if oSfa.exists(sUrl) then 'soubor s informacemi existuje
rem načíst celý soubor
oStream=oSfa.openFileRead(sUrl)
oTextStream=CreateUNOService("com.sun.star.io.TextInputStream")
with oTextStream
.InputStream=oStream
.Encoding=sEncoding
s=.readString(array(), false) 'načíst text z celého souboru
.closeInput
end with
oStream.closeInput
rem načíst první řádek a dva bajty po něm pro detekci Enteru
oStream=oSfa.openFileRead(sUrl)
oTextStream=CreateUNOService("com.sun.star.io.TextInputStream")
with oTextStream
.InputStream=oStream
.Encoding=sEncoding
sLine=.readLine() 'první řádek
.InputStream.seek(Len(sLine))
.InputStream.readBytes(aBytes, 2) 'dva bajty pro detekci Enteru
.closeInput
end with
oStream.closeInput
if ubound(aBytes)=-1 then
msgbox("Nedetekován Enter v souboru, zřejmě jen jeden řádek" & chr(13) & sUrl, 16)
stop
end if
rem detekce Enteru
if aBytes(0)=10 then 'LF
sEnter=chr(10) 'linux
elseif aBytes(0)=13 then 'CR
sEnter=chr(13) 'mac
if aBytes(1)=10 then sEnter=chr(13) & chr(10) 'CR+LF čili win
end if
if sEnter="" then 'špatná detekce Enteru, vzít Enter dle systému
select case getGuiType
case 3 'mac
sEnter=chr(13)
case 4 'linux
sEnter=chr(10)
case 1 'win
sEnter=chr(13) & chr(10)
case else 'something is wrong in detection of Enter according to OS
msgbox("Error in OS detection of Enter :-(")
stop
end select
end if
else 'soubor s informacemi neexistuje
msgbox("Neexistující soubor" & chr(13) & sUrl, 16)
stop
end if
loadFileString=split(s, sEnter) 'vrátit pole řádků
exit function
bug:
bug(Erl, Err, Error, "loadFileString")
End Function
Sub bug(sErl$, sErr$, sError$, sFce$) 'zruší dialogové okno a vypíše kde se stala chyba
msgbox("line: " & sErl & chr(13) & sErr & ": " & sError, 16, sFce)
stop 'zastavit ať nevypisuje několik msgboxů
End Sub