mandag den 17. oktober 2016

Hvilken kontorpakke skal man vælge til undervisningen i folkeskolen?

Google eller Microsoft. Hvilken kontorpakke skal man vælge til undervisningen i folkeskolen? Aarhus mener, begge løsninger er gode. København siger, Office365 er den bedste løsning.
»Landet ligger således, at Københavns Kommune er en Microsoft-kommune,«

Kilde: https://www.version2.dk/artikel/koebenhavns-kommune-office365-forbereder-eleverne-paa-virkelig-verden-991601

søndag den 16. oktober 2016

Lynkursus i makroprogrammering

Jeg har skrevet en række små artikler, hvor jeg skridt for skridt gennemgår et lille scenarie, hvor jeg importerer en kommasepareret fil og danner et diagram på baggrund af CSV-filen. Disse artikler er en god indgangsvinkel til at komme i gang med at lære makroprogrammering.

Makroer i regneark: http://libreofficedk.blogspot.dk/2016/09/programmering-af-makroer.html
Subrutiner og funktioner: http://libreofficedk.blogspot.dk/2016/10/subrutiner-og-funktioner.html
Lidt om objekter i UNO-api'et (debugging): http://libreofficedk.blogspot.dk/2016/10/lidt-om-objekter-i-uno-apiet.html
Grundlæggende regneark: http://libreofficedk.blogspot.dk/2016/10/i-sidste-maned-skrev-jeg-lidt-om.html
Konvertere tekst til datoer: http://libreofficedk.blogspot.dk/2016/10/makro-i-regneark-konverter-tekst-til.html
Håndtering af datoer i makroen: https://libreofficedk.blogspot.dk/2016/10/lidt-om-datoer-i-makro.html
Datoer i Calc: https://libreofficedk.blogspot.dk/2016/10/datoer-i-calc-med-makroer.html
Filnavne i makroer: http://libreofficedk.blogspot.dk/2016/10/filnavne-i-makroer.html
Importere en kommasepareret fil: http://libreofficedk.blogspot.dk/2016/10/mere-regnearks-gymnastik-makro.html
Indlæse en fil linje for linje: http://libreofficedk.blogspot.dk/2016/10/indlse-en-fil-linje-for-linje-makro.html
Håndtering af områder: http://libreofficedk.blogspot.dk/2016/10/makroer-i-regneark-handtering-af-omrader.html
Beregn antal rækker: http://libreofficedk.blogspot.dk/2016/10/vi-vil-gerne-et-skridt-videre-med-det.html
Opret diagram: http://libreofficedk.blogspot.dk/2016/10/makro-i-regneark-opret-et-diagram.html
Endnu et komplet eksempel, hvor makroen danner en årskalender med seks måneder per side: https://libreofficedk.blogspot.dk/2016/10/regneark-i-calc-arskalender.html

Filnavne i makroer

I artklen hvor vi indlæste data fra CSV-filen brugte jeg denne linje:
filename= "file:///home/leif/Skrivebord/Calc/Statistik.csv"

Det er på baggrund af min PC, som kører Linux, hvor jeg har lagt filen Statistik.csv i mappen Calc på skrivebordet. Den fysiske adresse er "/home/leif/Skrivebord/Calc/Statistik.csv".

På en Windowsmaskine kunne placeringen f.eks. være "c:\My Documents"

Læg mærke til at skråstregerne vender den anden vej på Windows i forhold til Linux.

Men læg også mærke til at når den fysiske adresse er /home/leif/Skrivebord/Calc/Statistik.csv så skal makroen kende den som file:///home/leif/Skrivebord/Calc/Statistik.csv. Det er fordi makroen skal bruge filplaceringen som var det en URL. Heldigvis kan vi konvertere en fysisk adresse til URL og omvendt

Sub ToFromURL
  Print ConvertToURL("/home/leif/Skrivebord/Calc/Statistik.csv")    'file:///home/leif/Skrivebord/Calc/Statistik.csv
  Print ConvertFromURL("file:///home/leif/Skrivebord/Calc/Statistik.csv") '/home/leif/Skrivebord/Calc/Statistik.csv
  Print ConvertToURL("c:\My Documents")               'file://c:/My%20Documents
  Print ConvertFromURL("file://c:/My%20Documents")    'c:\My Documents
End Sub


Når du skal vise en sti for brugeren skal du konvertere med ConvertFromURL
Når du skal bede brugeren om input, skal du efterfølgende konvertere med ConvertToURL for at LibreOffice forstår det.

Hvis du skal beregne en placering, som skal kunne anvendes på både Windows og Linux, så skal du aldrig anvende / eller \ i din beregning. Brug i stedet funktionen GetPathSeparator() som adskiller. På den måde får du returneret det rigtige tegn.

Sub filepath
sPathToFile = "C:\temp"
sCSVName   = "Statistik.csv"
sPathToCSV = sPathToFile & GetPathSeparator() & sCSVName

End sub

Vi kan få nogle brugbare informationer ud af makroen:
CurDir([s$])    '/home/leif
thisComponent.url 'file:///home/leif/Skrivebord/Calc/MakroTest.ods


Der er en række miljøvariabler som vi kan aflæse direkte. Det er:
$(inst): LibreOffice programmet rod
$(prog): LibreOffice programmet
$(user): Brugerkataloget (indstillinger osv.)
$(work): Brugerens arbejdsbibliotek, f.eks."MyDocuments"
$(home): Brugerens hjemmekatalog, f.eks. "Documents and Settings"
$(temp): Det aktuelle midlertidige bibliotek
$(path): Væ:rdien af miljøvatiablen PATH
$(langid): Sprogkode, f.eks. 1030 for dansk
$(vlang): Sprog, f.eks. "da"

Dem kan du aflæse sådan:
oPathSubst = createUnoService("com.sun.star.util.PathSubstitution")
Print oPathSubst.getSubstituteVariableValue("$(home)")


Her er et eksempel, hvor jeg beregner filsti og navn for min CSV-fil:

Sub FilePath
oPathSubst = createUnoService("com.sun.star.util.PathSubstitution")
homepath =  oPathSubst.getSubstituteVariableValue("$(home)")
file= homepath + GetPathSeparator() + "Skrivebord"+ GetPathSeparator() +"Calc"+ GetPathSeparator() +"Statistik.csv"
print file
End sub


fredag den 14. oktober 2016

Calc makro: Diagram fra ukendt antal rækker

Her er så den samlede makro, som opretter et linjediagram på baggrund af de udfyldte celler (uanset hvor mange rækker).

Resultatet:



Makroen:

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

Sub GetAllCells
  Dim oSheet
  Dim oCell
  Dim nEndCol As Integer
  Dim nEndRow As Integer
  oSheet = ThisComponent.Sheets.getByName("Statistik")           
  nEndCol = getLastUsedColumn(oSheet)
  nEndRow = getLastUsedRow(oSheet)
  oCell = oSheet.GetCellByPosition( nEndCol + 1, nEndRow + 1 )     
  Print oCell.AbsoluteName
  oAddress = oSheet.getCellRangeByPosition(0,0,nEndCol,nEndRow)
  oArea= oAddress.AbsoluteName     'på formen A3:B4
  CreateChart (oArea)              'her kalder vi næste subrutine
End Sub


Sub CreateChart (sDataRng)          'Modtager parameter
  sName = "Statistik-diagram"
  oSheets = thisComponent.Sheets
  oSheet = oSheets.getByName("Statistik")
  oAddress = oSheet.getCellRangeByName( sDataRng ).getRangeAddress()
  oCharts = oSheet.getCharts()
  If NOT oCharts.hasByName(sName) Then
    oRect       = createObject("com.sun.star.awt.Rectangle")
    oRect.X     = 10000    '1/100mm
    oRect.Y     = 1000
    oRect.width = 20000
    oRect.Height= 10000

    oCharts.addNewByName(sName, oRect, Array(oAddress), True, False)
  End If

  oChart = oCharts.getByName( sName )
  oChart.setRanges(Array(oAddress))
  oChart.HasRowHeaders=True
  oChart.HasColumnHeaders=True
  oChartDoc = oChart.getEmbeddedObject()

  oTitle = oChartDoc.getTitle()
  oTitle.String = "Nyhedsbrevet"

  ' Create a diagram.
  oDiagram = oChartDoc.createInstance( "com.sun.star.chart.LineDiagram" )
  oChartDoc.setDiagram( oDiagram )
  oDiagram = oChartDoc.getDiagram()
  oDiagram.DataRowSource = com.sun.star.chart.ChartDataRowSource.COLUMNS
End Sub

Function GetLastUsedColumn(oSheet) As Integer
  Dim oCursor
  oCursor = oSheet.createCursor
  oCursor.GotoEndOfUsedArea(True)
  GetLastUsedColumn = oCursor.RangeAddress.EndColumn
End Function

Function GetLastUsedRow(oSheet) As Integer
  Dim oCursor
  oCursor = oSheet.createCursor
  oCursor.GotoEndOfUsedArea(True)
  GetLastUsedRow = oCursor.RangeAddress.EndRow
End Function

Makro i regneark: Opret et diagram

Jeg har tidligere beskrevet hvordan de importerede data kan vises i et diagram. Det kan du læse om her: https://libreofficedk.blogspot.dk/2016/10/indlse-en-fil-linje-for-linje-makro.html

Men det kunne være spændende hvis vi kan oprette diagrammet "on the fly". Formålet er naturligvis at vi senere vil kombinere det med vores viden fra denne artikel https://libreofficedk.blogspot.dk/2016/10/vi-vil-gerne-et-skridt-videre-med-det.html hvor vi fandt ud af hvor mange rækker der er i regnearket.

Men først skal vi finde ud af hvordan vi opretter et diagram. Makroen er herunder, men jeg vil ikke gå i detaljer.

Læs gerne kommentarerne i koden:


REM  *****  BASIC  *****
Sub CreateChart

  sName = "Statistik-diagram"
    'Dataområdet (som vi senere laver om):
  sDataRng = "A1:B101"

  oSheets = thisComponent.Sheets
  oSheet = oSheets.getByName("Statistik")
  oAddress = oSheet.getCellRangeByName( sDataRng ).getRangeAddress()
  oCharts = oSheet.getCharts()
  If NOT oCharts.hasByName(sName) Then
    oRect       = createObject("com.sun.star.awt.Rectangle")


    'Placering:
    oRect.X     = 10000    '1/100mm
    oRect.Y     = 1000


    'Størrelse:
    oRect.width = 20000
    oRect.Height= 10000

    ' True betyder kolonne overskrifter.
    ' False betyder ingen række-overskrifter.
    oCharts.addNewByName(sName, oRect, Array(oAddress), True, False)
  End If

  oChart = oCharts.getByName( sName )
  oChart.setRanges(Array(oAddress))
  oChart.HasRowHeaders=True
  oChart.HasColumnHeaders=True
  oChartDoc = oChart.getEmbeddedObject()

    'Her danner vi titlen:
  oTitle = oChartDoc.getTitle()
  oTitle.String = "Nyhedsbrevet"

    'Opret diagrammet:
  oDiagram = oChartDoc.createInstance( "com.sun.star.chart.LineDiagram" )    'Linjediagram
  oChartDoc.setDiagram( oDiagram )
  oDiagram = oChartDoc.getDiagram()
  oDiagram.DataRowSource = com.sun.star.chart.ChartDataRowSource.COLUMNS    'Data i kolonner
End Sub


torsdag den 13. oktober 2016

Holland gør åbne standarder obligatoriske

Fra 2017 bliver det obligatorisk at bruge åbne standarder i offentlige myndigheder i Holland.

Det er det socialdemokratiske parlamentsmedlem Astrid Oosenbrug, der har stillet lovforslaget, og hun vurderer, at borgere og virksomheder kan spare penge ved at skifte til øget brug af åbne standarder.

Derudover vil interoperabiliteten også øges. Hun opfordrer derfor de offentlige forvaltninger til at overvinde deres frygt for forandring. I lovforslaget er der også instrukser til, hvordan regeringen aktivt bør fremme brugen af open source software.

Kilder:
https://www.version2.dk/artikel/hollands-parlamentet-goer-aabne-standarder-obligatoriske-990574
https://joinup.ec.europa.eu/node/156043

Beregn antal linjer/rækker i et ark

Vi vil gerne et skridt videre med det regneark vi importerede i en tidligere artikel. Du kan læse hvordan vi importerede data fra en CSV-fil her: http://libreofficedk.blogspot.dk/2016/10/indlse-en-fil-linje-for-linje-makro.html

Problemet med den importerede fil er blandt andet, at vi ikke på forhånd kender antallet af rækker i tabellen. Det vil være praktisk, hvis vi kan undersøge hvor mange rækker der er.

Sub testEndColRow
  oSheet = ThisComponent.Sheets.getByIndex(2)             
  nEndCol = getLastUsedColumn(oSheet)
  nEndRow = getLastUsedRow(oSheet)
  oCell = oSheet.GetCellByPosition(nEndCol+1, nEndRow+1)     
  Print oCell.AbsoluteName
End Sub


Function GetLastUsedColumn(oSheet) As Integer
  Dim oCursor
  oCursor = oSheet.createCursor
  oCursor.GotoEndOfUsedArea(True)
  GetLastUsedColumn = oCursor.RangeAddress.EndColumn
End Function


Function GetLastUsedRow(oSheet) As Integer
  Dim oCursor
  oCursor = oSheet.createCursor
  oCursor.GotoEndOfUsedArea(True)
  GetLastUsedRow = oCursor.RangeAddress.EndRow
End Function


Resultatet ser sådan ud: