Viser opslag med etiketten regneark. Vis alle opslag
Viser opslag med etiketten regneark. Vis alle opslag

lørdag den 26. oktober 2019

Nyt i 6.4: Import af XML-filer i Calc

Funktionen blev introduceret i version 6.3 som eksperimentiel funktion, men nu er den blevet mere stabil og ganske brugbar.

XML-filer findes alle vegne, fordi flere og flere programmer er begyndt at gemme data og indstillinger i XML-format. Og nu kan vi altså importere disse data ind i Calc. Formålet kan variere, alt efter hvad det er for data. I nogle tilfælde har vi måske lyst til at foretage beregninger, og i andre tilfælde vil vi bare gerne se data på en overskuelig måde.

Jeg har fundet en gammel GPX-fil, som er en rutevejledning fra min GPS. Den vil jeg gerne hente ind i Calc.

Vælg Data - XML-Kilde...
  1. Klik på knappen øverst og vælg filen.
  2. I vinduet i midten ser du et overblik over XML-filens struktur. Vælg hvilken del du vil importere (hvis der er flere).
  3. Vælg hvor i regnearket du vil importere data til.
  4. Klik på Importér


Resultatet er et pænt overblik over XML-filens indhold.


Vær opmærksom på at XML-filer kan være meget store, og det kan give problemer hvis din PC ikke har RAM nok.

onsdag den 25. september 2019

Tip: Formatering af tal i regneark

I regnearksprogrammet Calc kan du formatere værdierne præcis som du vil. Du kan benytte de indbyggede formater, fx valuta eller klokkeslæt.

Du har også mulighed for at designe dine egne formater, som passer til netop dit behov.

Et hyppigt problem er at CPR-numre er lidt specielle at  arbejde med, fordi jeg enten skal markere dem som tekst eller leve med at dem der starter med nul, mister første ciffer.

Men hvis vi formaterer cellerne med 0#####-#### ser det bedre ud. Værdien i cellen er et heltal, men det bliver vist som et rigtigt CPR-nummer:

søndag den 15. september 2019

Registrering af arbejdstid

I 2016 lavede jeg en evighedskalender, som jeg vil minde om. Der er tale om et regneark med en indbygget makro.

Du kan læse om kalenderen her: http://libreofficedk.blogspot.dk/2016/10/regneark-i-calc-arskalender.html
Du kan downloade regnearket her: https://www.dropbox.com/s/v6vi1pbbdmo0oz2/Kalender.ods?dl=0

Senest har jeg lavet en evighedskalender til registrering af arbejdstid.

På første fane vælger du årstal og indtaster din normale arbejdstid.

Herefter kan du måned for måned registrere hvornår du kommer og går. Efterhånden du udfylder dagene, kan du se resultatet i oversigten på første fane.

 

I kolonnen "Start" indtaster du hvornår du startede, fx 07:30, og i kolonnen "Slut" skriver du hvornår du gik igen, fx 16:00.

Hvis du selv betaler din frokostpause kan du korrigere for det ved at forøge den daglige arbejdstid med 30 minutter eller ved at skrive -00:30 i kolonnen "Ekstra". Den kolonne kan du også bruge, hvis du fx bliver kontaktet af din arbejdsplads uden for din normale arbejdstid, eller hvis du har taget noget arbejde med hjem.




Du kan downloade regnearket her: https://www.dropbox.com/s/ynuahdxua46jsbr/Tidsregistrering.ods?dl=1

Regnearket er udviklet i skrivebordsversionen, men kan sagtens bruges i LibreOffice Online.



Regnearket var egentlig ikke svært at lave, men der var dog et par små "knaster". Den første knast var at håndtere 29. februar som jo ikke skal anvendes med mindre det er skudår. Knasten endte med at løses ved at skifte til engelsk, fordi funktionen ISLEAPYEAR er oversat forkert til dansk (jeg har rettet det for fremtiden) og formlen virker fint i den danske version.

Den anden knast var at trække to klokkeslæt fra hinanden. Det går meget godt, men er resultatet en negativt tidangivelse, gik det galt. 07:30 minus 08:00 giver som udgangspunkt 23:30. Det betyder at 8 timer tidligere end 7:30 var klokken 23:30. Problemet blev løst ved manuelt at ændre formatet fra TT:MM til [TT]:MM.




søndag den 28. april 2019

Nye regnearksfunktioner

Igennem de seneste mange versioner af LibreOffice er der tilføjet adskillige nye regnearksfunktioner. Der er allerede nu planer om at implementere endnu en funktion i LibreOffice, nemlig Fouriertransformation.

Indrømmet. Det er en af de mere langhårede regnearksfunktioner, og jeg kan ikke lige huske hvornår jeg sidst har haft brug for den. Men den er altså på vej med LibreOffice 6.3.



Wikipedia om FOURIER-funktionen: https://da.wikipedia.org/wiki/Fouriertransformation

tirsdag den 20. november 2018

Tilpasset validering i regneark

I LibreOffice Calc (regneark) er det muligt at lægge validering på enkeltceller eller hele områder. Typisk vil du benytte denne mulighed for at sikre at indtastning i en celle ikke resulterer i fejl i beregninger andre steder i regnearket.

Du kan f.eks. sikre dig at en celle aldrig indeholder andet end tal, eller at årstallet altid er større end 1950. Måske vil du bare sikre dig at et felt ikke er tomt.

I LibreOffice 6.2 er det muligt at lave egne formler i valideringen. Hvis du eksempelvis ønsker at "styre" indtastningen i en mere direkte retning, f.eks. for at sikre et bestemt format.

Formlen "OG(VENSTRE(A1;3)="ID-";LÆNGDE(A1) >5)" vil sikre at indholdet af cellen A1 altid begynder med ID-"og altid er mindst 6 tegn lang.

lørdag den 2. december 2017

Kalender 2018

Når året er ved at rinde ud, kigger vi ofte med spænding hen imod det nye år der kommer. Hvad vil året bringe? Lykke, rigdom eller spændende oplevelser?

Det er tid at planlægge ferierne næste år, og til det skal vi bruge en kalender.

Sidste år udviklede jeg en evighedskalender, som jeg vil minde om. Der er tale om et regneark med en indbygget makro.

Du kan læse om kalenderen her: http://libreofficedk.blogspot.dk/2016/10/regneark-i-calc-arskalender.html
Du kan downloade regnearket her: https://www.dropbox.com/s/v6vi1pbbdmo0oz2/Kalender.ods?dl=0

mandag den 20. november 2017

Flyt kolonner eller rækker med musen

Hvis du vil flytte kolonner med musen, skal du være opmærksom på et par små finurligheder.

For det første:

For at flytte en kolonne, skal du gøre følgende:
  1. Marker kolonnen du vil flytte, ved at klikke på kolonneoverskriften (bogstavet).
  2. Fang nu en af cellerne i kolonnen (ikke kolonnneoverskriften) med musen
  3. Træk og slip kolonnen hvor du ønsker den indsat

For det andet:

Når du slipper kolonnen, vil du slippe den på/i en eksisterende kolonne, og som udgangspunkt overskriver du den pågældende kolonne.

Hvis du ikke vil overskrive kolonnen, men derimod indsætte imellem to kolonner, skal du holde Alt-tasten nede, når du slipper (ikke når du trækker).

For det tredje

Kolonnen du flytter/indsætter, bliver indsat til venstre for den kolonne du slipper den på, hvis du holder Alt-tasten nede.

Øvrige tips...

  • Vejledningen her kan desuden anvendes til at flytte rækker op og ned. Bare erstat Kolonne med Række.
  • Hvis du markerer flere kolonner, bliver alle de markerede kolonner flyttet.
  • Hvis du supplerer flytningen med at holde Ctrl-tasten nede når du slipper, vil du kopiere i stedet for at flytte kolonnen.
  • Hvis du supplerer yderligere med at holde skift-tasten nede (altså holder Ctrl+Alt+Skift nede) når du slipper, opretter du en ny kolonne med referencer til den kolonne du kopierede fra.
    Pas på her, for det kan være lidt af en finmotorisk udfordring.

Du kan læse vejledningen her: https://help.libreoffice.org/Calc/Moving_Cells_by_Drag-and-Drop/da

lørdag den 14. januar 2017

Nyt i 5.3: Flet ikke-tomme celler

Hvis du i et regneark forsøger at flette to celler, har du nu mulighed for at vælge, hvordan de to celler skal reagere.

I tidligere versioner var det muligt at flytte indholdet som tekst til første celle. Ellers blev indholdet skjult uden at blive slettet.



Fra version 5.3 bliver det muligt at vælge mellem
  • Flyt indholdet af cellerne til første celle
  • Bevare indholdet i skjult celle
  • Fjerne indholdet

Vær opmærksom på, at vælger du at flytte indholdet til den første celle, vil talværdier blive konverteret til tekst.
Forskellen på de to sidste valg er, at hvis du vælger at bevare indholdet skjult, kan du senere gendanne informationerne i cellen og du kan fortsat referere til cellen.

lørdag den 7. januar 2017

Mest læst i 2016

I november og december 2016 skrev jeg en række artikler om makroprogrammering i regneark, hvilket var ret populært. Hver artikel blev læst 3-400 gange.

Den mest læste artikel i 2016 var uden sammenligning artiklen om programmering af en årskalender i regneark, som blev læst 482 gange.

Fik du ikke læst artiklen, kan du finde den her: http://libreofficedk.blogspot.dk/2016/10/regneark-i-calc-arskalender.html.

Til de af jer der endnu ikke selv har fået lavet en kalender, kan I downloade et regneark her, hvor makroen er indbygget: https://dl.dropboxusercontent.com/u/9348527/Kalender.ods

 God fornøjelse.

torsdag den 22. december 2016

Regneark for eksperter

Er du en haj til regneark, eller vil du gerne være en haj?

Så kan du sikkert have interesse i to vejledninger som er målrettet universitetsstuderende. Niveauet er forholdsvis højt, men jeg tror alligevel de fleste kan få nytte af eksemplerne.

Introduktion til statistik

Dana Lee Ling er professor ved universitetet i Mikronesien, og har blandt sine mange akademiske opgaver, at undervise sine studerende i statistik. Han har skrevet en vejledning  “Introduction to Statistics Using LibreOffice Calc”.

Vejledningen introducerer emner som populationer og prøver, måling af middelværdi og spredning, visualisering af data, parrede data og scatter-diagrammer, sandsynlighed, fordelinger, normalfordelingen, og z-værdier, konfidensintervaller for middelværdien, hypotesetest mod en kendt populations middelværdi og hypotesetest af to prøver middelværdier.

Du kan finde vejledningen (engelsk) her: http://www.comfsm.fm/~dleeling/statistics/text5.html
 

Problemløsning (solver-funktion)

Er du mere til problemløsning har Harvard University og MIT offentliggjort en introduktion til anvendelsen af "Problemløser...". Funktionen kan løse både lineære og ikke-lineære programmeringsfunktioner.

Denne vejledning er en trin-for-trin guide som fører dig igennem opgaven:
1) Indlæs problemløseren til dit regneark
2) Definer problemet og skriv formler for formål og begrænsninger
3) Løs problemet

Du kan finde vejledningen (engelsk) her: https://courses.edx.org/asset-v1:MITx+CTL.SC2x_2+2T2016+type@asset+block/Solver_Tutorial_and_Debug_v1.pdf

mandag den 5. december 2016

Nyt i 5.3: Microsoft Office interoperabilitet

Hver eneste version af LibreOffice indeholder forbedringer til både eksport til og import fra Microsoft Office. Her er en kort oversigt over hvilke forbedringer vi kan forvente i forhold til Microsoft Offices .xlsx og .xls:
  • Liggende format (landskab) gemmes nu korrekt ved eksport til .xlsx (MS Excel kompatibel)
  • Skjulte og tomme rækker bliver skjult, ved eksport til .XLSX eller .xls-fil
  • Dispositionskolonner og rækker gemmes korrekt ved eksport til XLSX
  • Ved eksport til .xlsx gemmes XML_outlineLevelRow og XML_outlineLevelCol nøgler korrekt (Office365 kompatibel)
  • Ved efter eksport til XLSX og XLS dannes korrekt kolonnebredden i MS Excel til OS X,
  • Præcis kolonnebredden ifølge MS' specifikation
  • Brugerdefineret formatering, som ikke blev anvendt ved import af XLSX dokumenter
  • Eksport af farvede tomme celler til .xlsx og .xls-dokumenter
  • Kompatibilitet problem med Excel 2007 efter eksport til .xlsx rettet
  • Langsom import af grupperede pivottabeller i .xlsx rettet
  • Talformater:
    • Bevare escape-tegn
    • Brøkformat accepterer '0' ud over '#' og '?'
    • Udvidet LCID kan importeres. Udvidet LCID bruges til at eksportere kalender og lokale tal

torsdag den 3. november 2016

Calc makro: Kopiere indhold

Foranlediget af et spørgsmål på LibreOffice forum:
Hvordan kan man kopiere et bestemt område fra et ark til markørens position i et hvilket-som-helst ark i regnearksdokumentet.

Den pågældende spørger vil gerne kopiere fra et skjult ark, hvilket denne løsning desværre ikke opfylder. Årsagen er at jeg anvender klippe-klistre, og det kan man ikke fra et ark man ikke kan se.

Koden:

Sub Main
oDoc=thisComponent


'husk markeringen
Selection=oDoc.CurrentSelection.getRangeAddress
oSheets = oDoc.Sheets


'Det område vi ønsker at kopiere (kilde)
SourceArea =  oDoc.Sheets.getByName("Data").getCellRangeByName("A1:B8")


'Marker området
oDoc.CurrentController.Select(SourceArea)

document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")


'Kopier det markerede
dispatcher.executeDispatch(document, ".uno:Copy", "", 1, Array())


'Find tilbage til markeringen
oSheet = oDoc.getSheets().getByIndex(Selection.Sheet)
oCell = oSheet.GetCellbyPosition( Selection.StartColumn, Selection.StartRow )
oDoc.CurrentController.Select(oCell)


'Indsæt
dispatcher.executeDispatch(document, ".uno:Paste", "", 0, Array())

End Sub

tirsdag den 25. oktober 2016

Regneark i Calc (Årskalender)

Efter at vi tidligere har gennemgået en række dato-funktioner i Calc regneark, vil jeg vise et praktisk eksempel. Makroen herunder danner en to-sidet kalender med helligdage, med seks måneder på hver side. Der er forklarende kommentarer i koden.

Eksempel:




REM  *****  BASIC  *****

Sub Main

this_year = InputBox ("Indtast årstal mellem 1583 og 3000", "Vælg årstal", year(date))

'Kontroller at årstallet brugbart
If (1583 > val(this_year) OR val(this_year) > 3000) then
MsgBox("Årstallet skal være mellem 1583 og 3000", 48, "Fejl")
Stop
End If

Cal_name="Kalender " & this_year

'Kontroller at dokumentet er et regneark
my_doc = ThisComponent
If not my_doc.SupportsService("com.sun.star.sheet.SpreadsheetDocument") then
MsgBox("Dokumentet skal være et regneark", 48, "Fejl")
Stop
End if

my_sheets = my_doc.Sheets
antal=my_sheets.count

If NOT my_sheets.hasbyName(Cal_name) Then

my_sheets.insertNewByName(Cal_name, antal)

End If

the_sheet = my_sheets.getByName(Cal_name)

'Formatér siden
oStyles = my_doc.StyleFamilies.getByName("PageStyles")
    oPstyle = oStyles.getByName(the_sheet.PageStyle)
    oPstyle.FooterIsOn = False
    oPstyle.FooterIsOn = False
    oPstyle.TopMargin=500

'Første linje   
  oRange = the_sheet.getCellRangeByName("A1:L1")
  oRange.merge(True)
  oCell= the_sheet.getCellByPosition(0, 0)
  oCell.String = Cal_name
  FormatDark(oCell)

  oRange = the_sheet.getCellRangeByName("M1:X1")
  oRange.merge(True)
  oCell= the_sheet.getCellByPosition(12, 0)
  oCell.String = Cal_name
  FormatDark(oCell)
 
'Nederste linje    
  oRange = the_sheet.getCellRangeByName("A34:X34")
  oRange.merge(True)
  oCell = the_sheet.getCellRangeByName("A34")
  FormatDark(oCell)

For m = 1 to 12
'Overskriften

  oRange = the_sheet.getCellRangeByPosition(m*2-1-1,1,m*2-1,1)
  oRange.merge(True)
  the_cell = the_sheet.getCellByPosition(m*2-1-1, 1)
  the_cell.String=TheMonthName(m)
  the_cell.HoriJustify = 2
  the_cell.CellBackColor=rgb(150,150,150)
  the_cell.CharColor=rgb(255,255,255)

'Justerer kolonnebredder
  Column= the_sheet.Columns(m*2-1-1)
  Column.Width=550
  Column= the_sheet.Columns(m*2-1)
  Column.Width=4000

Next m 

'For hver måned...
For m = 1 to 12

'Dag for dag...
For d= 1 to Day(LastDayOfMonth(DateValue("1-" & m & "-" & this_year))
the_date=DateValue(d & "-" & m & "-" & this_year)

'Skriv datoen i første kolonne
the_cell = the_sheet.getCellByPosition(m*2-1-1, d + 1)
the_cell.Value=the_date
the_cell.NumberFormat=109
'Formatter cellen
FormatLight(the_cell)

'Skriv ugedagens bogstav i anden kolonne
the_Othercell = the_sheet.getCellByPosition(m*2-1, d + 1)

'Lørdag og søndag formateres
    Select Case WeekDay(the_date)
    Case 1
        FormatLight(the_Othercell)
        the_Othercell.String="S"
    Case 2
        the_Othercell.String="M"
    Case 3
        the_Othercell.String="T"
    Case 4
        the_Othercell.String="O"
    Case 5
        the_Othercell.String="T"                       
    Case 6
        the_Othercell.String="F"
    Case 7
        FormatLight(the_Othercell)
        the_Othercell.String="L"               
End Select

'Tilføj helligdage
generic_date= left(STR(the_date),5)
oFA = createUnoService( "com.sun.star.sheet.FunctionAccess" )

'Faste helligdage
Select Case generic_date

case "01-01"
        FormatLight(the_Othercell)
        the_Othercell.String=the_Othercell.String & " Nytårsdag"
case "05-06"
        FormatLight(the_Othercell)
        the_Othercell.String=the_Othercell.String &" Grundlovsdag"
case "24-12"
        FormatLight(the_Othercell)
        the_Othercell.String=the_Othercell.String &" Juleaften"
case "25-12"
        FormatLight(the_Othercell)
        the_Othercell.String=the_Othercell.String &" Juledag"
case "26-12"
        FormatLight(the_Othercell)
        the_Othercell.String=the_Othercell.String &" 2. Juledag"               

'Skæve helligdage
'Der findes ingen påske-beregning i Basic, men vi kan eksekvere regnearksfunktionen =Påskedag)
        the_Othercell.String=the_Othercell.String &" Påskedag"
case Left(STR(CDate(oFA.callFunction( "EASTERSUNDAY", array( this_year ) )+1 ) ),5)
        FormatLight(the_Othercell)
        the_Othercell.String=the_Othercell.String &" 2. Påskedag"     
case Left(STR(CDate(oFA.callFunction( "EASTERSUNDAY", array( this_year ) )-2 ) ),5)
        FormatLight(the_Othercell)
        the_Othercell.String=the_Othercell.String &" Langfredag"              
case Left(STR(CDate(oFA.callFunction( "EASTERSUNDAY", array( this_year ) )-3 ) ),5)
        FormatLight(the_Othercell)
        the_Othercell.String=the_Othercell.String &" Skærtorsdag"
case Left(STR(CDate(oFA.callFunction( "EASTERSUNDAY", array( this_year ) )+49 ) ),5)
        FormatLight(the_Othercell)
        the_Othercell.String=the_Othercell.String &" Pinsedag"      
case Left(STR(CDate(oFA.callFunction( "EASTERSUNDAY", array( this_year ) )+50 ) ),5)
        FormatLight(the_Othercell)
        the_Othercell.String=the_Othercell.String &" 2. Pinsedag"   
case Left(STR(CDate(oFA.callFunction( "EASTERSUNDAY", array( this_year ) )+26 ) ),5)
        FormatLight(the_Othercell)
        the_Othercell.String=the_Othercell.String &" St. Bededag"   
        case Left(STR(CDate(oFA.callFunction( "EASTERSUNDAY", array( this_year ) )+39 ) ),5)
        FormatLight(the_Othercell)
        the_Othercell.String=the_Othercell.String &" Kr. Himmelfartsdag"            
End Select

Next d    'Dags-loopet slutter
Next m    'Måneds-loopet slutter

End Sub

Function LastDayOfMonth(d As Date) As Date
'Beregn hvor mange dage i måneden
  Dim nYear As Integer
  Dim nMonth As Integer
  nYear = Year(d)        'Current year
  nMonth = Month(d) + 1  'Next month, unless it was December.
  If nMonth > 12 Then    'If it is December then nMonth is now 13
    nMonth = 1           'Roll the month back to 1
    nYear = nYear + 1    'but increment the year
  End If
  LastDayOfMonth = CDate(DateSerial(nYear, nMonth, 1)-1)
End Function

Function TheMonthName(m)
'Omsætter månedstal til månedsnavn
CompatibilityMode(True)
TheMonthName=MonthName(m)
End Function

Sub FormatLight(oCell)
'Formatér lys grå
        oCell.CellBackColor=rgb(200,200,200)
        oCell.CharColor=rgb(255,255,255)
End Sub

Sub FormatDark(oCell)
'Formatér overskrift
  oCell.CharHeight=18
  oCell.HoriJustify = 2
  oCell.CellBackColor=rgb(100,100,100)
  oCell.CharColor=rgb(255,255,255)
End Sub 

tirsdag den 11. oktober 2016

Makro i regneark: Konvertér tekst til dato

I den makro jeg har brugt som demonstration, og hvor vi indlæste CSV-filen linje for linje, så vi denne "krølle":

If c=0 Then
        t= split(s, "-", 3)
        s=DateSerial(t(2), t(1), t(0))
End if
        my_cell.Value=s
  

Du kan læse artiklen her: http://libreofficedk.blogspot.dk/2016/10/indlse-en-fil-linje-for-linje-makro.html

Forklaring:
s er den tekst vi modtager fra CSV-filen, og vi ved at formatet er i tekstformatet "dd-mm-åååå". Hvis vi indsætter teksten som streng (my_cell.String=s) vil indholdet af cellen få tekstformat og hvis vi indsætter teksten som en værdi (my_cell.Value=s) vil indholdet blive fortolket og omsat til et mere eller mindre tilfældig heltal (muligvis en intern datoværdi).

Vi bliver altså nødt til at fortolke tekststrengen og splitte den op i flere elementer. Kommandoen kunne lyde: Split tekststrengen op i tre dele, hvor "-" er adskiller:
split(s, "-", 3)

Du kan læse mere om Split-funktionen her: https://help.libreoffice.org/Basic/Split_Function_Runtime/da

Sæt derefter de tre dele sammen til en datoværdi:
DateSerial(t(2), t(1), t(0))

Du kan læse mere om DateSerial-funktionen her: https://help.libreoffice.org/Basic/DateSerial_Function_Runtime/da


mandag den 10. oktober 2016

Indlæse en fil linje for linje (makro)

I en tidligere artikel beskrev jeg hvordan vi kan importere en CSV-fil igennem LibreOffices importfilter. Artiklen kan du finde her: http://libreofficedk.blogspot.dk/2016/10/mere-regnearks-gymnastik-makro.html

Der er flere fordele ved den metode, men der er også ulemper. F.eks. kan det være besværligt at finde de korrekte parametre til importen, og vi har ikke helt kontrol over hvad der egentlig sker. En konsekvens er blandt andet, at vi ikke kan importere data ind i et eksisterende regneark uden at 'ødelægge' arkets layout. Det viser sig ved at formatering af arket bliver overskrevet.

I denne artikel vil jeg beskrive en anden metode, hvor vi indlæser data linje for linje og behandler indholdet. Hvilken metode du synes er bedst er op til dig, men undervejs lærer vi også lidt mere om programmering i LibreOffice.

Vi indleder makroen på samme måde som vi har set tidligere:
filename= "file:///home/leif/Skrivebord/Calc/Statistik.csv"
my_doc = ThisComponent
my_sheets = my_doc.Sheets
antal=my_sheets.count
If NOT my_sheets.hasbyName("Statistik") Then
    my_sheets.insertNewByName("Statistik", antal)
End If
the_sheet = my_sheets.getByName("Statistik")


Der burde ikke være ret mange overraskelser i den del. Vi har nu kontrol over dokumentet, og vi har et ark at arbejde med.

Nu skal vi så til at arbejde med filen. Først skal vi have lavet en kanal at indlæse filen igennem. FreeFile er en kommando, som giver os et heltal, som udtrykker første ledige kanal. Så åbner vi filen (variablen filename blev defineret tidligere) og vi vælger metoden 'For Input', hvilket betyder at vi læser, vi skriver ikke (Input = read, Output = write). Til sidst starter vi et loop (fortsæt så længe vi ikke er færdige):
r=0    'Nulstil variabel for rækkenummer
n = FreeFile
Open filename For Input As #n
Do While NOT EOF(n)


Nu starter så logikken
  • r er rækkenummer (0...n)
  • c er kolonnenummer (0-1)
Vi får data ind fra filen celle for celle, så vi må hele tiden kontrollere om vi er i kolonne 0 (datokolonnen) eller 1 (værdikolonnen).
Vi skal også holde øje med om vi er i række 0, fordi så er det kolonneoverskriften vi har med at gøre.

Kolonneoverskriften er tekst, og skal håndteres med .String
Første kolonne er en dato, men udtrykt som tekst. Teksten skal lige konverteres til en brugbar dato og indsættes med .Value.
Anden kolonne er tal, som også indsættes med .Value.

For c = 0 to 1    'Tæl mellem første og anden kolonne
    Input #n, s    'Læs data
    my_cell = the_sheet.getCellByPosition(c,r)    'Peg på den rigtige celle
    If r=0 then    'Hvis rækkenummeret er 0
        my_cell.String=s    'Det er en streng
    Else
        If c=0 Then    'Det er en dato
            s=DateValue(s)          'Tekst til datoformat
            my_cell.NumberFormat=36    'Cellen får datoformat
        End if
        my_cell.Value=s

    End if
Next c        'Næste kolonne
r=r+1        'Læg en til rækkenummeret
Loop        'Afslut loopet


Læs mere om håndtering af datoer i Calc her: http://libreofficedk.blogspot.dk/2016/10/datoer-i-calc-med-makroer.html 
Læs mere om datoformat i i makroer her: http://libreofficedk.blogspot.dk/2016/10/lidt-om-datoer-i-makro.html

Nu mangler vi faktisk kun at lukke for vores datakanal:
Close #n

Hele makroen:
REM  *****  BASIC  *****

Sub Main
filename= "file:///home/leif/Skrivebord/Calc/Statistik.csv"
my_doc = ThisComponent
my_sheets = my_doc.Sheets
antal=my_sheets.count
the_sheet=checksheet("Statistik", 255, 3, 101)

n = FreeFile
r=0
Open filename For Input As #n
Do While NOT EOF(n)

    For c = 0 to 1
        Input #n, s
        my_cell = the_sheet.getCellByPosition(c,r)
  
        If r=0 then
        my_cell.String=s
        Else
        If c=0 Then
            s=DateValue(s)
            my_cell.NumberFormat=36  
        End if
        my_cell.Value=s

        End if
'       Her lidt ekstra guf for øjet
        If isEven (r) then
        my_cell.CellBackColor=rgb(100,100,100)
        my_cell.CharColor=rgb(255,255,255)
        else
        my_cell.CellBackColor=rgb(250,250,250)
        End if
    Next c
    r=r+1

Loop
Close #n
End Sub


Resultatet:

Efterfølgende har jeg oprettet et diagram, som visualiserer de første 100 rækker fra mit regneark. Diagrammet opdateres automatisk hver gang jeg indlæser nye data fra min CSV-fil:



torsdag den 6. oktober 2016

Mere regnearks-gymnastik (makro)

Vi vil gerne lidt mere end bare løbe rundt i cellerne. I denne omgang skal vi se hvordan vi kan hente data fra en CSV-fil.

Filen er en simpel fil med to kolonner:


Det er såmænd en statistik over hvor mange der abonnerer på nyhedsbrevet.


Først skal vi have defineret nogle variable:

Den fil jeg gerne vil importere:
filename= "file:///home/leif/Skrivebord/Calc/Statistik.csv"

Som sædvanligt dokumentet:
my_doc = ThisComponent

Og vi skal have styr på arkene i dokumentet:
my_sheets = my_doc.Sheets
antal=my_sheets.count


Nu skal vi lige undersøge om vores ark allerede findes, eller om vi skal oprette et nyt. Baggrunden er at jeg gerne vil sikre at jeg ikke overskriver vigtige data andre steder i mit regneark.

Kort fortalt, så opretter jeg arket "Statistik", hvis ikke det findes i forvejen:
If NOT my_sheets.hasbyName("Statistik") Then
my_sheets.insertNewByName("Statistik", antal)
End If
the_sheet = my_sheets.getByName("Statistik")


Når vi indlæser CSV-filen skal vi bruge nogle "magiske" import-parametre. For at gøre en lang historie kort, så svarer filter_valg til de valg du kan gøre i import-dialogen i LibreOffice:
filter = "Text - txt - csv (StarCalc)"
filter_valg = "44,34,0,1,1/2/2/1/3/2"
tilstand = com.sun.star.sheet.SheetLinkMode.NORMAL


Her kommer så den egentlige import:
the_sheet.link(filename, "", filter, filter_valg, tilstand)

Hvis du IKKE ønsker at data skal indsættes som kæde, kan du tilføje denne linje:
the_sheet.setLinkMode(com.sun.star.sheet.SheetLinkMode.NONE)

Makroen, som faktisk ikke er særlig stor, ser sådan ud:

REM  *****  BASIC  *****

Sub ImportCSV
filename= "file:///home/leif/Skrivebord/Calc/Statistik.csv"
my_doc = ThisComponent
my_sheets = my_doc.Sheets
antal=my_sheets.count

If NOT my_sheets.hasbyName("Statistik") Then
my_sheets.insertNewByName("Statistik", antal)
End If

the_sheet = my_sheets.getByName("Statistik")

filter = "Text - txt - csv (StarCalc)"
filter_valg = "44,34,0,1,1/2/2/1/3/2"
tilstand = com.sun.star.sheet.SheetLinkMode.NORMAL

the_sheet.link(filename, "", filter, filter_valg, tilstand)
the_sheet.setLinkMode(com.sun.star.sheet.SheetLinkMode.NONE)

End Sub