Fără programare
Datele firmelor direct în foaia ta de calcul
Registrul, TVA, adresa și bilanțul oricărei firme din România, cu o formulă în Google Sheets, cu Power Query în Excel sau într-un flux automat în Zapier, Make și n8n. Ai nevoie doar de o cheie API.
Formule noi în Google Sheets
- 1Deschide foaia în Google Sheets și alege Extensii > Apps Script.
- 2Șterge ce e acolo, lipește scriptul de alături și salvează (Ctrl+S).
- 3Reîncarcă foaia: apare meniul „FirmeAPI”. Alege „Setează cheia API” și lipește cheia ta.
- 4Scrie în orice celulă =FIRMA("33741906"; "denumire").
Ce poți scrie
=FIRMA("33741906"; "denumire")Numele firmei
=FIRMA(A2; "stare")Starea din registru, pentru CUI-ul din A2
=FIRMA(A2; "adresa_sediu_social.judet")Câmpurile din interior, cu puncte
=FIRMA(A2; "tva.platitor")Plătitor de TVA (TRUE / FALSE)
=BILANT(A2; "cifra_afaceri")Cifra de afaceri din ultimul an depus
=BILANT(A2; "profit_net"; 2023)Profitul net pe 2023
=FIRMEAPI("caen/" & A2; "caen_principal.cod")Orice rută din documentație, orice câmp
Indicatori pentru BILANT: cifra_afaceri, venituri_totale, cheltuieli_totale, profit_brut, profit_net, datorii, capitaluri, active_imobilizate, active_circulante, angajati (sau codul, ex. I13). Răspunsurile se țin minte 6 ore, ca recalcularea foii să nu consume credite.
firmeapi-google-sheets.gsDescarcă
/**
* FirmeAPI.ro pentru Google Sheets
*
* Formule noi in foaia ta:
* =FIRMA("33741906"; "denumire") orice camp din datele firmei
* =FIRMA("33741906"; "adresa_sediu_social.judet") campurile din interior, cu puncte
* =BILANT("33741906"; "cifra_afaceri") ultimul an depus
* =BILANT("33741906"; "profit_net"; 2023) un an anume
* =FIRMEAPI("restante/33741906"; "") orice ruta din documentatie, orice camp
*
* Instalare: Extensii > Apps Script, lipesti acest cod, salvezi, apoi din
* meniul „FirmeAPI” al foii alegi „Seteaza cheia API”. Cheia ramane in contul
* tau Google (proprietatile utilizatorului), nu in foaie.
*
* Raspunsurile se tin minte 6 ore: aceeasi formula, recalculata, nu consuma
* credite de fiecare data.
*/
var FIRMEAPI_ADRESA = 'https://www.firmeapi.ro/api/v1/';
var FIRMEAPI_CACHE_SECUNDE = 6 * 60 * 60;
// Indicatorii din bilant, dupa denumirea lor (codurile I1…I20 difera dupa tipul formularului).
var FIRMEAPI_INDICATORI = {
cifra_afaceri: /cifra de afaceri/,
venituri_totale: /venituri totale/,
cheltuieli_totale: /cheltuieli totale/,
profit_brut: /profit brut/,
pierdere_bruta: /pierdere bruta/,
profit_net: /profit net/,
pierdere_neta: /pierdere neta/,
active_imobilizate: /active imobilizate/,
active_circulante: /active circulante/,
stocuri: /stocuri/,
creante: /creante/,
casa_banci: /casa/,
datorii: /datorii/,
capitaluri: /capitaluri/,
angajati: /salariati/,
};
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('FirmeAPI')
.addItem('Setează cheia API', 'firmeapiSeteazaCheia')
.addItem('Golește memoria (recitește datele)', 'firmeapiGolesteMemoria')
.addToUi();
}
function firmeapiSeteazaCheia() {
var ui = SpreadsheetApp.getUi();
var r = ui.prompt('Cheia API FirmeAPI', 'O găsești în contul tău, la „Chei API”.', ui.ButtonSet.OK_CANCEL);
if (r.getSelectedButton() === ui.Button.OK) {
PropertiesService.getUserProperties().setProperty('FIRMEAPI_CHEIE', r.getResponseText().trim());
ui.alert('Gata. Formulele =FIRMA(...) și =BILANT(...) folosesc acum cheia ta.');
}
}
function firmeapiGolesteMemoria() {
PropertiesService.getUserProperties().setProperty('FIRMEAPI_GENERATIE', String(Date.now()));
SpreadsheetApp.getUi().alert('Gata. Formulele vor citi din nou datele (consumă credite).');
}
/**
* Un camp din datele firmei (registru, ANAF, TVA, adresa).
*
* @param {string} cui CUI-ul firmei, cu sau fara RO
* @param {string} camp ex. denumire, stare, cod_caen, nr_reg_com, adresa, tva.platitor, adresa_sediu_social.judet
* @return valoarea
* @customfunction
*/
function FIRMA(cui, camp) {
return firmeapiCampul(firmeapiCere('firma/' + firmeapiCui(cui)).data, camp || 'denumire');
}
/**
* Un indicator din bilantul unei firme.
*
* @param {string} cui CUI-ul firmei
* @param {string} camp ex. cifra_afaceri, profit_net, venituri_totale, datorii, capitaluri, angajati, sau un cod (I13)
* @param {number} an optional: anul bilantului; fara el, ultimul an depus
* @return valoarea
* @customfunction
*/
function BILANT(cui, camp, an) {
var ani = (firmeapiCere('bilant/' + firmeapiCui(cui)).data || {}).ani || {};
var lista = Object.keys(ani).map(function (k) { return ani[k]; }).filter(function (a) { return a && a.an; });
if (!lista.length) throw new Error('Firma nu are bilanțuri depuse.');
lista.sort(function (a, b) { return b.an - a.an; });
var bilant = an ? lista.filter(function (a) { return String(a.an) === String(an); })[0] : lista[0];
if (!bilant) throw new Error('Nu există bilanț pe ' + an + '.');
var cheie = String(camp || '').trim();
if (cheie === 'an' || cheie === 'denumire' || cheie === 'caen' || cheie === 'denumire_caen') return bilant[cheie];
var tipar = FIRMEAPI_INDICATORI[cheie.toLowerCase()];
var detalii = bilant.detalii || [];
for (var i = 0; i < detalii.length; i++) {
var d = detalii[i];
var nume = firmeapiFaraDiacritice(d.val_den_indicator || '');
if ((tipar && tipar.test(nume)) || String(d.indicator).toUpperCase() === cheie.toUpperCase()) return d.val_indicator;
}
throw new Error('Indicatorul „' + camp + '” nu există în bilanțul pe ' + bilant.an + '.');
}
/**
* Orice ruta din API, orice camp din raspuns.
*
* @param {string} ruta ex. "restante/33741906" sau "caen/33741906"
* @param {string} cale campul, cu puncte: ex. "caen_principal.cod"; gol = tot raspunsul, ca text
* @return valoarea
* @customfunction
*/
function FIRMEAPI(ruta, cale) {
var data = firmeapiCere(String(ruta).replace(/^\/+/, '').replace(/^(api\/)?v1\//, '')).data;
if (!cale) return JSON.stringify(data);
return firmeapiCampul(data, cale);
}
/* ── Intern ─────────────────────────────────────────────────────────── */
function firmeapiCui(cui) {
var c = String(cui).replace(/\D/g, '');
if (!c) throw new Error('CUI lipsă sau greșit.');
return c;
}
function firmeapiFaraDiacritice(s) {
return String(s).toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g, '');
}
function firmeapiCampul(data, cale) {
var v = String(cale).split('.').reduce(function (o, k) { return o == null ? null : o[k]; }, data);
if (v === undefined) throw new Error('Câmpul „' + cale + '” nu există în răspuns.');
return v != null && typeof v === 'object' ? JSON.stringify(v) : v;
}
function firmeapiCere(ruta) {
var p = PropertiesService.getUserProperties();
var cheie = p.getProperty('FIRMEAPI_CHEIE');
if (!cheie) throw new Error('Setează cheia: meniul FirmeAPI > Setează cheia API.');
var cache = CacheService.getUserCache();
var cheieCache = 'f:' + (p.getProperty('FIRMEAPI_GENERATIE') || '0') + ':' + ruta;
var tinut = cache.get(cheieCache);
if (tinut) return JSON.parse(tinut);
var r = UrlFetchApp.fetch(FIRMEAPI_ADRESA + ruta, {
headers: { 'X-API-KEY': cheie, Accept: 'application/json' },
muteHttpExceptions: true,
});
var corp = r.getContentText();
var json;
try { json = JSON.parse(corp); } catch (e) { throw new Error('Răspuns neașteptat (' + r.getResponseCode() + ').'); }
if (r.getResponseCode() >= 400 || json.success === false) {
throw new Error((json.error && (json.error.message || json.error)) || json.message || ('Eroare ' + r.getResponseCode()));
}
if (corp.length < 90000) cache.put(cheieCache, corp, FIRMEAPI_CACHE_SECUNDE);
return json;
}