Åbne virksomhedsdata

Peter Brodersen, Septima

Om Peter

  • Født i 1978 (41 år gammel)
  • Autodidakt
  • Web siden 1997
  • Selvstændig i 2003
  • Findvej.dk i 2006
  • Hos Septima siden 2018
  • Elsker åbne data (og lange ture på stranden)

Virksomhedsdata

Erhvervsworkshop

Hvad er virksomhedsdata?

Stamdata

CVR-nummer, navn, adresse, virksomhedsform, branchekode, binavne, reklamebeskyttelse, ejerforhold, P-numre, m.m.

Nuværende og historisk data

Årsrapporter

Årsberetning i prosatekst, revideret og godkendt

Regnskabstal

Rettigheder og omfang

Data er frikøbt!

Kan hentes gratis og må bruges frit
(hvis man overholder reglerne om reklamebeskyttelse)

Årsrapporter er for "offentlige" virksomheder:
ApS, A/S, m.fl.

Dog undtaget: Banker, filialer af udenlandske virksomheder, m.fl.

Vejen til frie data

Harddisks

Grunddata, L71 (2012-2013)

  • Vedtaget af et enigt folketing 19. december 2012.
  • Grunddata omfatter bl.a. GIS-data (ortofoto, højdemodel, FOT-/GeoDanmark-data, m.m.)
  • Data officielt tilgængelige fra 1. januar 2013
  • CVR-data blev også frikøbt 1. januar 2013

Men hvad med regnskaberne?

  • Regnskaber kostede penge:
    • PDF: 37 kr.
    • XBRL: 15 kr.
  • Ingen mængderabat
  • Ingen ophavsret
  • De jure-monopol (Erhvervsstyrelsen)
  • De facto-monopol (Experian)

Workshop om erhvervsdata

Erhvervsstyrelsen inviterede myndigheder, virksomheder, journalister, græsrodsfolk til workshop 19. december 2013.

Ingen ku' li' datamonopolister!

Staten fik dokumenteret ønske og behov fra erhvervslivet.

Regnskabsdata blev frit tilgængelige i 2015-ish.

Datakilder og brugere

Skildpadde og plastic i havet

Datafordeleren

(don't go there!)

(undskyld)

CVR.dk

cvr.dk

Virk.dk

  • Virk: Erhvervsstyrelsen (Erhvervsministeriet)
  • REST-API'er op imod Elasticsearch
  • Både stamdata og årsrapporter
  • Daglige opdateringer

cvrapi.dk

Tredjepart, CVR API ApS

https://cvrapi.dk/api?search=30083377&country=dk

{
   "vat": 30083377,
   "name": "ALLER TRYK NORDEN A/S",
   "address": "Havneholmen 33",
   "zipcode": 1561,
   "city": "København V",
   "cityname": null,
   "protected": false,
   "phone": 43505400,
   "email": null,
   "fax": null,
   "startdate": "29/11 - 2006",
   "enddate": "01/02 - 2017",
   "employees": "10-19",
   "addressco": null,
   "industrycode": 581410,
   "industrydesc": "Udgivelse af ugeblade og magasiner",
   "companycode": 60,
   "companydesc": "Aktieselskab",
   "creditstartdate": null,
   "creditbankrupt": false,
   "creditstatus": null,
   "owners": null,
   "productionunits": [
      {
         "pno": 1012828442,
         "main": true,
         "name": "ALLER TRYK NORDEN A/S",
         "address": "Havneholmen 33",
         "zipcode": 1561,
         "city": "København V",
         "cityname": null,
         "protected": false,
         "phone": 43505400,
         "email": null,
         "fax": 36442333,
         "startdate": "29/11 - 2006",
         "enddate": "01/02 - 2017",
         "employees": null,
         "addressco": null,
         "industrycode": 581410,
         "industrydesc": "Udgivelse af ugeblade og magasiner"
      }
   ],
   "t": 100,
   "version": 6
}
  

Øvrige brugere

Proff

Experian

BiQ

Septima OneDoor

Visma Rating

CVRnet

Hvordan henter man data fra Virk.dk?

Disketter

Forskel på at hente stamdata og årsrapporter

  • Stamdata
    • API kræver login (HTTP authentication).
    • Data er lige til at bruge.
  • Årsrapporter
    • API kræver ikke login.
    • Det hentede er "kun" en dokumentoversigt.
    • Output bruges til derefter at hente filer.
    • Man kan ikke søge inde i årsrapporterne.

System-til-system adgang til CVR-data

For at få adgang til løsningen skal du skrive til cvrselvbetjening@erst.dk. Herefter vil du få tilsendt en mail med detaljer om adgangen, herunder anmodning om underskrift af en erklæring om, at du vil overholde betingelsen for modtagelse af data om reklamebeskyttede enheder. Bemærk, at der forekommer sagsbehandlingstid.

Søgning i stamdata, CVR-nummer

http://distribution.virk.dk/cvr-permanent/virksomhed/_search?q=Vrvirksomhed.cvrNummer:30083377

{
   "took":1,
   "timed_out":false,
   "_shards":{
      "total":6,
      "successful":6,
      "skipped":0,
      "failed":0
   },
   "hits":{
      "total":1,
      "max_score":12.363823,
      "hits":[
         {
            "_index":"cvr-v-20181028",
            "_type":"_doc",
            "_id":"4001596586",
            "_score":12.363823,
            "_source":{
               "Vrvirksomhed":{
                  "cvrNummer":30083377,
                  "regNummer":[

                  ],
                  "brancheAnsvarskode":null,
                  "reklamebeskyttet":false,
                  "navne":[
                     {
                        "navn":"ALLER MEDIA GROUP A/S",
                        "periode":{
                           "gyldigFra":"2006-11-29",
...
  

Søgning i stamdata, flere resultater

http://distribution.virk.dk/cvr-permanent/virksomhed/_search?q=
Vrvirksomhed.virksomhedMetadata.nyesteNavn.navn:Disruption
+AND+Vrvirksomhed.virksomhedsform.kortBeskrivelse:IVS
&size=100

{
  "took":4,
  "timed_out":false,
  "_shards":{
    "total":6,
    "successful":6,
    "skipped":0,
    "failed":0
  },
  "hits":{
    "total":3,
    "max_score":17.600994,
    "hits":[
      {
        "_index":"cvr-v-20181028",
        "_type":"_doc",
        "_id":"4006865615",
        "_score":17.600994,
        "_source":{
          "Vrvirksomhed":{
            "cvrNummer":38580434,
            "regNummer":[

            ],
            "brancheAnsvarskode":null,
            "reklamebeskyttet":false,
            "navne":[
              {
                "navn":"X-disruption IVS",
                "periode":{
                  "gyldigFra":"2017-04-19",
                  "gyldigTil":null
                },
                "sidstOpdateret":"2017-04-20T00:19:27.000+02:00"
              }
            ],
            "binavne":[

            ],
            "postadresse":[

            ],
            "beliggenhedsadresse":[
              {
                "landekode":"DK",
                "fritekst":null,
                "vejkode":400,
...
  

Søgning i årsrapporter, CVR-nummer:

http://distribution.virk.dk/offentliggoerelser/_search?q=cvrNummer:43325612&size=100

(husk at angive size; Virk.dks default-size er kun på 10)

{
  "took":3,
  "timed_out":false,
  "_shards":{
    "total":3,
    "successful":3,
    "skipped":0,
    "failed":0
  },
  "hits":{
    "total":11,
    "max_score":1.0,
    "hits":[
      {
        "_index":"indberetninger-20180424",
        "_type":"_doc",
        "_id":"urn:ofk:oid:21250011",
        "_score":1.0,
        "_source":{
          "indlaesningsId":null,
          "sagsNummer":"11-383.928",
          "regnskab":{
            "regnskabsperiode":{
              "slutDato":"2011-09-30",
              "startDato":"2010-10-01"
            }
          },
          "sidstOpdateret":"2012-01-19T23:00:00.000Z",
          "cvrNummer":30083377,
          "dokumenter":[
            {
              "dokumentType":"AARSRAPPORT",
              "dokumentMimeType":"image/tiff",
              "dokumentUrl":"http://regnskaber.virk.dk/77338003/Y3ZyLmRrOi8vcGRmcy8zMDA4MzM3NztBL1MzODkxNzU7MjAxMDEwMDE7MjAxMTA5MzA7UjtS.tif"
            }
          ],
          "regNummer":null,
          "indlaesningsTidspunkt":"2018-04-02T02:59:35.195Z",
          "offentliggoerelsesTidspunkt":"2012-01-19T23:00:00.000Z",
          "omgoerelse":false,
          "offentliggoerelsestype":"regnskab"
        }
      },
      {
        "_index":"indberetninger-20180424",
        "_type":"_doc",
        "_id":"urn:ofk:oid:21990926",
        "_score":1.0,
        "_source":{
          "indlaesningsId":null,
          "sagsNummer":"X16-AQ-34-DD",
          "regnskab":{
            "regnskabsperiode":{
              "slutDato":"2015-09-30",
              "startDato":"2014-10-01"
            }
          },
          "sidstOpdateret":"2016-02-15T15:18:42.596Z",
          "cvrNummer":30083377,
          "dokumenter":[
            {
              "dokumentType":"AARSRAPPORT",
              "dokumentMimeType":"application/pdf",
              "dokumentUrl":"http://regnskaber.virk.dk/77338003/ZG9rdW1lbnRsYWdlcjovLzAzLzhkL2RmLzM4Lzc3L2JhZWEtNDU0Yy05ZTgxLTVhZTk3N2ZkZmYxOQ.pdf"
            },
            {
              "dokumentType":"AARSRAPPORT",
              "dokumentMimeType":"application/xml",
              "dokumentUrl":"http://regnskaber.virk.dk/77338003/ZG9rdW1lbnRsYWdlcjovLzAzLzI1LzNhLzRjLzg4LzM4ZGEtNDM2NC04OThiLTgzNmM3MDUxYmZlMQ.xml"
            }
          ],
          "regNummer":null,
          "indlaesningsTidspunkt":"2018-03-28T20:14:57.844Z",
          "offentliggoerelsesTidspunkt":"2016-02-15T15:18:42.470Z",
          "omgoerelse":false,
          "offentliggoerelsestype":"regnskab"
        }
      },
...
  

Årsrapporter, resultat

  • Liste over indrapporteringer og tilhørende filer.
  • Typiske formater: TIFF, PDF, XBRL, iXBRL.
  • PDF er ikke normaliseret; kan være indscannet.
  • Kun resultater for år, hvor filer er tilgængelige.
  • Flere årsrapporter (før 1994-ish) kan ligge offline.
    Dem bliver vi ikke oplyst om.
  • Husk at gemme resultatet! Filer kan rumme fejl.

Hent alle årsrapporter!

Filerne i resultatsættet for årsrapporter

XBRL, PDF, iXBRML

"dokumenter":[
  {
    "dokumentUrl":"http://regnskaber.virk.dk/78626313/ZG9rdW1lbnRsYWdlcjovLzAzLzUwL2FkLzhjLzA0LzJlMTgtNDlmNy05ZTQwLWEyMmI0ZDdmNDYzMw.xml",
    "dokumentMimeType":"application/xml",
    "dokumentType":"AARSRAPPORT"
  },
  {
    "dokumentUrl":"http://regnskaber.virk.dk/78626313/ZG9rdW1lbnRsYWdlcjovLzAzL2E0LzZhL2JkL2EwLzJmNzMtNDMzNC05ZjA1LWVkMDY5MDNlNmFhNg.pdf",
    "dokumentMimeType":"application/pdf",
    "dokumentType":"AARSRAPPORT"
  },
  {
    "dokumentUrl":"http://regnskaber.virk.dk/78626313/ZG9rdW1lbnRsYWdlcjovLzAzLzQyL2YxLzNmLzJhL2IwMGMtNDBlOC1iYzE0LWRiMTU0OTgyMTZjMw.xhtml",
    "dokumentMimeType":"application/xhtml+xml",
    "dokumentType":"AARSRAPPORT"
  }
]
  

XBRL

XBRL-logo

Hvad er XBRL?

eXtensible Business Reporting Language

  • XML-baseret format til udveksling af forretningsdata.
  • Påbegyndt i 1998, fremlagt i 2003.
  • Få ændringer i standard siden da.
  • Mange mulige taksonomier.
  • Alle "offentlige" virksomheder skal indrapportere årsrapporter i XBRL-format siden 2011.

"XML, siger du?"

"XML... som overholder XML-standarden, men der stopper sammenligningen også... Der bliver teknikere overraskede, hvis de selv har XML kørende... Så lad være med at ringe, det har vi ikke ressourcer til."

Fra Gå-hjem-møde: Digitale regnskaber
22. januar 2015

Umiddelbare forbehold

  • Al XML fra Virk.dk validerer!
  • Selve indholdet er dog stort set ikke kontrolleret.
  • Et XBRL-dokument kan (og vil) rumme flere årsrapporter.
  • Meget indhold referer til øvrige felter.
  • Vil typisk kræve efterbehandling før brug.
    (ingen effektiv ren XML-løsning i database) [oxymoron?]

Eksempel på XBRL

Eksempel på XBRL-indhold

"Dér stopper sammenligningen også"

<?xml version="1.0" encoding="UTF-8"?><xbrli:xbrl xmlns:xbrli="http://www.xbrl.org/2003/instance" xmlns="http://www.w3.org/1999/xhtml" xmlns:dst="http://xbrl.dcca.dk/dst" xmlns:cmn="http://xbrl.dcca.dk/cmn" xmlns:sob="http://xbrl.dcca.dk/sob" xmlns:link="http://www.xbrl.org/2003/linkbase" xmlns:iso4217="http://www.xbrl.org/2003/iso4217" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ref="http://www.xbrl.org/2006/ref" xmlns:xh11d="http://www.w3.org/1999/xhtml/datatypes/" xmlns:arr="http://xbrl.dcca.dk/arr" xmlns:ixt="http://www.xbrl.org/inlineXBRL/transformation/2010-04-20" xmlns:lnk="http://www.xbrl.org/2003/linkbase" xmlns:xbrldt="http://xbrl.org/2005/xbrldt" xmlns:basis="http://xbrl.dcca.dk/Regnskab%202.0%20Basis" xmlns:ifrs="http://xbrl.iasb.org/taxonomy/2009-04-01/ifrs" xmlns:ix="http://www.xbrl.org/2008/inlineXBRL" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mrv="http://xbrl.dcca.dk/mrv" xmlns:xl="http://www.xbrl.org/2003/XLink" xmlns:fsa="http://xbrl.dcca.dk/fsa" xmlns:xbrldi="http://xbrl.org/2006/xbrldi" xmlns:gsd="http://xbrl.dcca.dk/gsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink">
..
<xbrli:scenario>
  <xbrldi:explicitMember dimension="fsa:ResultDistributionDimension">fsa:RetainedEarningsMember</xbrldi:explicitMember>
</xbrli:scenario>
  

Element på 212 tegn:

StatementWhetherAuditedFinancialStatementsGiveTrueAndFairViewOfAssetsLiabilitiesFinancialPositionAndResultInAccordanceWithApplicableFinancialReportingFrameworkOrMeetAnyOtherCorrespondingGeneralQualityRequirements

Yeti Network Browser

https://yeti2.corefiling.com/

Screenshot af Yeti

Datakvalitet

Dårligt placerede bogstaver

Version2.dk bragte et par artikler i 2018

Hvor opstår fejlene

Fejl begås af:

  • Firmaer
  • Revisorer
  • Erhvervsstyrelsen
  • Databrugerne

Et lille udsnit …

Tre forskellige resultater
Milliard i stedet for million
År 3000

Forkert CVR-nummer i XBRL-fil!

Regnskab for CVR 19849732:
Forkert CVR-nummer
CVR 00000000

Hvor langt ligger CVR-numre fra hinanden?

Difference i CVR-numre

Vigtigt: Brug Elasticsearch-resultatet som kilde!

Kreditvurdering?

Visma Rating

Visma Rating

Fratrådt bestyrelsen i 2008

Men stadigvæk med en aktiv rolle som "Stifter" indtil konkurs.

Sæsonfrugt - ejer

Kodeeksempel

Find rapporter med bestemt ord

Eksempel i Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Peter Brodersen, So ein GIS Ding 4
import json
import requests
from xml.etree import ElementTree as ET

cvrid = 43325612 # Aller Media A/S
field = '{http://xbrl.dcca.dk/fsa}DisclosureOfContingentLiabilities' # Oplysning om eventualforpligtelser
search = 'erstatning'

searchUrl = 'http://distribution.virk.dk/offentliggoerelser/_search?q=cvrNummer:' + str(cvrid) + '&size=100'

data = requests.get(searchUrl).content
j = json.loads(data)

for hit in j["hits"]["hits"]:
  for dokument in hit["_source"]["dokumenter"]:
    if dokument["dokumentMimeType"] == 'application/xml' and dokument["dokumentType"] == 'AARSRAPPORT':
      print ("Checking: " + hit["_source"]["regnskab"]["regnskabsperiode"]["startDato"] + " - " + hit["_source"]["regnskab"]["regnskabsperiode"]["slutDato"])
      xmlContent = requests.get(dokument["dokumentUrl"]).content # requests library decompresses "Content-Encoding: gzip" automatically, no need to manually gunzip
      root = ET.fromstring(xmlContent);
      for disclosure in root.findall(field):
        if disclosure.text.find(search) != -1:
          print (disclosure.text)
  

Resultat

$ ./cvr_xbrl_segd4.py
Checking: 2014-10-01 - 2015-09-30
Checking: 2015-10-01 - 2016-09-30
Checking: 2016-10-01 - 2017-09-30
Aller Media A/S har indgået en 10 års uopsigelig huslejeaftale, som løber frem til juli 2019, hvorpå der påhviler en samlet huslejeforpligtelse på 70 mio.kr. pr. 30 september 2017.

Øvrig leje-/leasingforpligtelser udgør 4,5 mio.kr. pr. 30 september 2017.

I forlængelse af Se og Hør sagen har en række kendte personligheder stævnet Aller Media A/S m.fl. for uretmæssigt at bringe privatlivsnyheder og reportager i ugeblade i årene 2008 - 2012. Selskabet afviser stævningens krav, som anses for uberettiget og i øvrigt anses for forældet. Det opgjorte krav udgør samlet 6,0 mio.kr.

En ledende medarbejder har anlagt erstatningskrav på ca. 3,5 mio.kr. mod selskabet for uberettiget afskedigelse. Selskabet afviser kravet fuldstændigt og i sin helhed, og forventer at vinde sagen ved den kommende voldgift.

Selskabet indgår i en dansk sambeskatning med Aller Holding A/S som administrationsselskab. Selskabet hæfter derfor i henhold til selskabsskattelovens regler herom for indkomstskatter mv. for de sambeskattede selskaber ligeledes for eventuelle forpligtelser til at indeholde kildeskat på renter, royalties og udbytter for de sambeskattede selskaber.

Der er afgivet støtteerklæring til to datterselskaber, hvormed Aller Media A/S i perioden frem til den 1. januar 2019 forpligter sig på anfordring at tilføre likviditet, således datterselskaberne kan varetage deres forpligtelser over for tredjemand. Indeståelsen er uigenkaldelig.
Checking: 2017-10-01 - 2018-09-30
Checking: 2012-10-01 - 2013-09-30
Checking: 2013-10-01 - 2014-09-30

Lokal kopi?

  • XML-filer fylder ca. 60 GB
  • Tilsvarende til database og indeksering
  • Mulighed for fritekst-søgning
  • Væsentligt arbejde med kvalitetssikring

Fritekst-søgning

SELECT COUNT(DISTINCT cvr)
FROM cvr.reports
WHERE value_tokens @@ to_tsquery('danish', 'ulovligt & anpartshaverlån');
count
1112

CVR 28859422

ÅrNote
2005-2006
2007-2008Ledelsen har beklageligvis bevilget et ulovligt anpartshaverlån, som dog med ledelsens forslag til udlodning af udbytte fra årets resultat vil blive indfriet.
2009-2012Ledelsen har beklageligvis bevilget et ulovligt anpartshaverlån, men ledelsen vil efterfølgende indfri dette.
2013-2017Ledelsen har beklageligvis bevilget et ulovligt anpartshaverlån.
2018Ledelsen har beklageligvis bevilget et ulovligt anpartshaverlån. I forbindelse med udlodning af udbytte i 2019 vil lånet blive indfriet.

Tak fordi I er til!

Mail: peter@septima.dk

Twitter: @peterbrodersen

Slides kan hentes på Firmadata.dk

Spørgsmål?