Otomatisasi Pelacakan Pengeluaran Freelancer di Sheets
Bangun pengkategorisasi pengeluaran otomatis di Google Sheets dengan pemetaan kolom dinamis, tabel aturan vendor, dan output untuk P&L atau burn model.
Panduan ini memandu Anda membangun pengkategorisasi pengeluaran otomatis di Google Sheets yang menormalisasi ekspor bank dan payment processor yang berantakan, memetakan string vendor ke kategori menggunakan tabel aturan yang mudah dikelola, dan menyalurkan data aktual bulanan yang bersih ke dalam struktur P&L - yang bisa Anda jadikan acuan dalam burn model atau tunjukkan kepada investor.
Yang Anda Perlukan
- Akun Google dengan akses Google Sheets
- Ekspor CSV dari bank, Stripe, Mercury, atau alat akuntansi
- Pemahaman dasar tentang SUMIFS, INDEX/MATCH, dan formula array
- Daftar kategori yang sesuai dengan lini item P&L Anda (Software, Payroll, Marketing, dll.) - bukan kategori laporan pajak standar
- (Opsional) Akses Google Apps Script untuk dataset lebih dari 2.000 baris
Panduan Langkah demi Langkah
Buat Arsitektur 3 Tab
Pisahkan alur data Anda ke dalam 3 tab: Import, Expenses, dan Summary. Ini terdengar sederhana, tetapi sebagian besar pelacak pengeluaran yang gagal disebabkan oleh seseorang yang menempelkan ekspor CSV langsung di atas formula aktif. Itu menghapus formula, data menjadi mentah, dan tidak ada yang teragregasi dengan benar.
- Import**: Zona tempel mentah - tidak ada formula di sini, selamanya. Data CSV ditempelkan di sini dan dibiarkan tidak tersentuh.
- Expenses**: Lapisan normalisasi. Setiap baris di sini adalah formula yang menarik data dari Import, dibersihkan dan dikategorikan.
- Summary**: Agregasi murni. SUMIFS terhadap Expenses, dikelompokkan berdasarkan kategori dan bulan.
- Rules**: Tab terpisah yang memetakan pola kata kunci vendor ke nama kategori. Anda memelihara ini secara independen dari semua logika formula.
Pro Tip
Lindungi tab Import dari pengeditan tidak disengaja menggunakan Data → Protect sheets and ranges. Sangat mudah untuk tidak sengaja mengetik di suatu sel dan merusak zona tempel.Bangun Pencari Kolom Dinamis
Ekspor bank, pembayaran Stripe, dan unduhan alat akuntansi tidak selalu hadir dalam urutan kolom yang sama setiap bulan. Mercury menempatkan tanggal di kolom A; perangkat lunak akuntansi Anda mungkin menaruhnya di kolom D. Urutan itu juga bisa bergeser saat Anda mengubah pengaturan ekspor atau menambahkan kolom data baru.
Solusinya adalah pencarian baris header yang menemukan kolom yang tepat berdasarkan nama, bukan posisi. Di tab Expenses, definisikan 3 sel pembantu yang menyimpan indeks kolom untuk setiap kolom yang Anda butuhkan:
=MATCH("Date", Import!$1:$1, 0)
=MATCH("Description", Import!$1:$1, 0)
=MATCH("Amount", Import!$1:$1, 0)
Beri nama sel-sel ini col_date, col_desc, col_amount menggunakan Name Box. Kemudian di baris Expenses, tarik data secara dinamis:
=INDEX(Import!$A:$Z, ROW(A2), col_date)
=INDEX(Import!$A:$Z, ROW(A2), col_desc)
=INDEX(Import!$A:$Z, ROW(A2), col_amount)
Sekarang ketika ekspor Anda hadir dengan Description di kolom C alih-alih kolom B bulan depan, tidak ada yang rusak. Pencarian baris header menemukannya dan setiap formula hilir menyesuaikan secara otomatis.
Pro Tip
Tambahkan MATCH keempat untuk kolom apa pun yang bervariasi berdasarkan sumber - "Memo", "Reference", "Counterparty" semuanya muncul di posisi berbeda tergantung pada bank.Normalisasi String Vendor
String vendor mentah dari ekspor bank sering bermasalah: spasi di akhir string, huruf campuran, spasi berlebih dari kolom OCR, dan artefak enkode. Dua transaksi dari vendor yang sama bisa terlihat sangat berbeda bagi formula SEARCH jika salah satunya memiliki spasi terselip.
Di tab Expenses, tambahkan kolom Vendor_Clean yang menerapkan tiga transformasi secara berurutan:
=TRIM(UPPER(SUBSTITUTE(C2, " ", " ")))
TRIM menghapus spasi di awal dan akhir. UPPER menghilangkan perbedaan huruf besar/kecil. SUBSTITUTE menyatukan spasi ganda yang terkadang muncul di kolom memo yang diekspor. Kolom tunggal ini adalah yang akan direferensikan oleh setiap formula hilir - deskripsi impor mentah tetap tidak tersentuh di kolomnya sendiri sebagai jejak audit.
Untuk normalisasi tanggal, tambahkan kolom Date_Clean. Format tanggal campuran - MM/DD/YYYY vs YYYY-MM-DD vs "16 Apr 2026" - umum terjadi saat menarik data dari berbagai sumber. Paksa ke nilai standar:
=IF(ISNUMBER(D2), D2, DATEVALUE(D2))
Pro Tip
Format Date_Clean sebagai tanggal, bukan general. DATEVALUE mengembalikan nomor serial yang terlihat seperti "46000-sekian" sampai Anda menerapkan pemformatan tanggal.Bangun Tabel Aturan Vendor
Tab Rules memuat tabel 2 kolom: Keyword di kolom A, Category di kolom B. Inilah satu-satunya tempat yang Anda ubah ketika vendor baru muncul atau Anda ingin mengklasifikasi ulang suatu kategori.
| Keyword | Category |
|---|---|
| ZOOM | Software |
| GOOGLE CLOUD | Software |
| AWS | Software |
| NOTION | Software |
| FACEBOOK ADS | Marketing |
| Marketing | |
| STRIPE FEE | Payment Processing |
| GUSTO | Payroll |
| UNITED AIRLINES | Travel |
Ada beberapa aturan desain yang perlu diperhatikan. Keyword sebaiknya cocok dengan bagian paling khas dari string vendor - bukan "GOOGLE" (terlalu luas, menangkap Google Drive, Google Ads, dan Google Cloud sebagai satu hal) melainkan "GOOGLE CLOUD" atau "GOOGLE ADS" secara spesifik. Tidak ada batasan jumlah aturan per kategori; akurasi adalah prioritasnya. Payment processor yang menghasilkan 7 varian string berbeda untuk vendor yang sama membutuhkan 7 baris keyword.
Urutkan Keyword berdasarkan spesifisitas dalam setiap kategori - pola yang lebih spesifik lebih dahulu. Pengkategorisasi mengembalikan kecocokan pertama, jadi "FACEBOOK ADS" harus muncul sebelum "FACEBOOK" jika keduanya ada di tabel Anda.
Pro Tip
Tambahkan kolom ketiga, Notes, untuk mencatat alasan suatu aturan dibuat. Ketika Anda kembali ke tabel ini 6 bulan kemudian dan bertanya-tanya mengapa "AMZN MKTPLACE" dipetakan ke Software alih-alih Miscellaneous, Anda akan menghargai konteks tersebut.Tulis Pengkategorisasi INDEX/MATCH
Formula kategori memindai tabel Rules Anda untuk menemukan keyword apa pun yang muncul di dalam string vendor yang sudah dibersihkan. Di tab Expenses, tambahkan kolom Category:
=IFERROR(INDEX(Rules!$B$2:$B$100, MATCH(TRUE, ISNUMBER(SEARCH(Rules!$A$2:$A$100, E2)), 0)), "Uncategorized")
Masukkan ini dengan Ctrl+Shift+Enter untuk menjadikannya formula array (di Sheets versi terbaru, Anda juga bisa membungkus ekspresi dalam ARRAYFORMULA). Formula ini mengembalikan kategori pertama yang keyword-nya muncul di mana saja dalam string vendor yang dibersihkan - pencocokan parsial berfungsi, sehingga "GOOGLE CLOUD STORAGE" dengan tepat mengenai aturan "GOOGLE CLOUD" meskipun tidak identik.
Fallback "Uncategorized" lebih penting dari yang terlihat. Jika Anda mengembalikan "" untuk baris yang tidak cocok, transaksi tersebut diam-diam menghilang dari total SUMIFS - SUMIFS melewati sel kosong. Menggunakan string eksplisit berarti pengeluaran yang tidak cocok muncul sebagai kategori tersendiri di ringkasan Anda, di mana Anda bisa melihat dengan tepat apa yang belum dipetakan. Visibilitas itulah yang memberi tahu Anda kapan tabel Rules perlu diperbarui.
Pro Tip
Setelah menjalankan formula, filter kolom Category untuk "Uncategorized" dan urutkan berdasarkan Amount secara menurun. Transaksi terbesar yang tidak cocok menunjukkan dengan tepat aturan mana yang perlu ditambahkan terlebih dahulu.Bangun Grid Ringkasan SUMIFS
Tab Summary mengagregasi total berdasarkan kategori dan bulan. Siapkan grid dengan kategori di kolom A dan bulan di baris 1 (diformat sebagai hari pertama setiap bulan, misalnya 2026-01-01). Kemudian untuk setiap sel dalam grid:
=SUMIFS(Expenses!$F:$F, Expenses!$G:$G, $A2, Expenses!$H:$H, ">="&B$1, Expenses!$H:$H, "<"&EDATE(B$1, 1))
Di mana kolom F adalah Amount, kolom G adalah Category, dan kolom H adalah Date_Clean. EDATE(B$1, 1) membatasi rentang tanggal ke bulan kalender tanpa perlu hardcode tanggal akhir.
Tambahkan baris Total di bagian bawah (SUM setiap kolom bulan) dan baris Budget tempat Anda hardcode rencana pengeluaran per kategori. Varians adalah Aktual dikurangi Budget:
=B3 - B2
Terapkan conditional formatting pada sel varians: merah untuk melebihi anggaran, hijau untuk di bawah. Ini adalah pemeriksaan yang berguna, tetapi bukan output akhir - ini adalah lapisan input.
Pro Tip
Gunakan referensi seluruh kolom dengan hati-hati.Expenses!$F:$F berfungsi baik dalam praktik, tetapi memindai 1.000.000 baris untuk 200 baris data aktual membuang waktu kalkulasi ulang pada sheet besar. Batasi rentang Anda ke Expenses!$F$2:$F$5000 setelah Anda mengetahui volume data Anda.Hubungkan Ringkasan ke Struktur P&L
Ini adalah langkah yang paling sering dilewatkan oleh panduan pelacak pengeluaran lainnya. Grid Summary dari Langkah 6 berguna untuk pembukuan internal, tetapi bukan model keuangan - ini hanya tabel datar. Agar berguna sebagai input untuk burn model atau P&L yang bisa ditunjukkan kepada investor, Anda membutuhkan tab P&L terpisah yang memperlakukan Summary sebagai lapisan Aktual.
Siapkan tab P&L dengan struktur lini item lengkap di kolom A, selaras dengan cara biaya muncul dalam laporan laba rugi nyata:
| Lini Item | Jan | Feb | Mar |
|---|---|---|---|
| Pendapatan | |||
| Harga Pokok Penjualan | |||
| - Hosting & Infrastruktur | |||
| - Payment Processing | |||
| Laba Kotor | |||
| Beban Operasional | |||
| - Software & Langganan | |||
| - Payroll | |||
| - Marketing | |||
| - Perjalanan Dinas | |||
| Total OpEx | |||
| EBITDA |
Setiap sel Aktual di P&L menarik dari Summary menggunakan referensi langsung atau SUMIFS yang memetakan lini item P&L ke kategori Summary:
=SUMIFS(Summary!$B:$B, Summary!$A:$A, "Software")
Untuk kategori yang digabung ke satu lini P&L (misalnya, "Hosting & Infrastruktur" mungkin menggabungkan baris Summary untuk AWS, Google Cloud, dan Cloudflare), gunakan beberapa SUMIFS:
=SUMIFS(Summary!B:B,Summary!A:A,"Software") + SUMIFS(Summary!B:B,Summary!A:A,"Hosting")
Inilah arsitekturnya: pengkategorisasi mengisi Summary, Summary adalah lapisan input Aktual, dan tab P&L adalah modelnya. Pendapatan masuk ke P&L secara langsung atau dari sumber datanya sendiri. Dari sini, aktual bulanan Anda mengalir secara alami ke perhitungan burn rate dan runway - untuk struktur tersebut, lihat cara menghitung runway startup dan dashboard burn rate startup.
Pro Tip
Tambahkan baris Budget di P&L yang mereferensikan tab asumsi terpisah, bukan nilai hardcode. Varians anggaran di P&L menjadi=Aktual - Budget, dan setiap revisi anggaran hanya memerlukan perubahan satu sel di asumsi.Otomatisasi Pemasukan Data dengan Apps Script
Formula array di Langkah 5 menjalankan perbandingan N × M setiap kali kalkulasi ulang - setiap baris di Expenses dipindai terhadap setiap baris di tabel Rules. Pada 500 baris pengeluaran terhadap tabel rules 50 baris, itu 25.000 pencarian per kalkulasi ulang. Pada 10.000 baris, menjadi 500.000, dan Anda akan memperhatikan sheet membeku selama beberapa detik setiap kali ada sel yang berubah.
Untuk dataset lebih dari 2.000 baris, pindahkan kategorisasi ke Apps Script. Logikanya identik, tetapi berjalan sekali dan menulis hasilnya dalam satu batch:
function categorizeExpenses() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const expenses = ss.getSheetByName('Expenses');
const rules = ss.getSheetByName('Rules');
const expData = expenses.getDataRange().getValues();
const ruleData = rules.getRange(2, 1, rules.getLastRow() - 1, 2).getValues();
const categories = [];
for (let i = 1; i < expData.length; i++) {
const vendor = String(expData[i][4]).toUpperCase(); // Vendor_Clean column
let matched = 'Uncategorized';
for (const [keyword, category] of ruleData) {
if (vendor.includes(String(keyword).toUpperCase())) {
matched = category;
break;
}
}
categories.push([matched]);
}
// Single batch write - never write inside the loop
expenses.getRange(2, 6, categories.length, 1).setValues(categories);
}
Aturan kritis: jangan pernah memanggil setValue() di dalam loop. Setiap penulisan individual memicu round-trip ke Sheets API. Pada 10.000 baris, menulis di dalam loop bisa memakan waktu lebih dari 15 menit. Batch setValues() di akhir menjalankan operasi yang sama dalam waktu kurang dari 10 detik.
Hubungkan ini ke trigger melalui Extensions → Apps Script → Triggers agar berjalan otomatis saat diedit, atau atur agar aktif ketika tab Import berubah. Per April 2026, batas waktu eksekusi Apps Script adalah 6 menit untuk akun konsumen dan 30 menit untuk akun Workspace - pola batch write membuat Anda tetap nyaman dalam kedua batas tersebut bahkan pada batas maksimum Google Sheets sebesar 10 juta sel.
Pro Tip
TambahkanSpreadsheetApp.flush() setelah setValues() jika Anda menggabungkan beberapa batch write. Tanpanya, Sheets mungkin mem-buffer perubahan dan menerapkannya dalam urutan yang salah.Kesimpulan
Yang telah Anda bangun adalah pipeline data, bukan sekadar pelacak. Import adalah zona tempel yang bertahan dalam format ekspor apa pun. Expenses menormalisasi dan mengkategorikan. Summary mengagregasi. P&L mengonsumsi. Setiap lapisan melakukan satu pekerjaan dan menyerahkan ke lapisan berikutnya - artinya ketika bank mengubah format CSV mereka atau Anda menambahkan kategori vendor baru, Anda mengubah satu hal dan sisanya diperbarui secara otomatis.
Kesalahan yang paling sering dilakukan oleh pengaturan pengeluaran adalah memperlakukan grid Summary sebagai output akhir. Itu bukan. Itu adalah feed aktual. Begitu Anda menghubungkannya ke tab P&L dengan pendapatan dan struktur lini item yang tepat, ini berhenti menjadi latihan pembukuan dan mulai menjadi model keuangan.
Coba ModelMonkey gratis selama 14 hari - berfungsi di Google Sheets dan Excel, dan dapat menangani kategorisasi, pengkabelan formula, serta pengaturan struktur P&L melalui satu percakapan.
Pertanyaan Umum
Mengapa pengkategorisasi INDEX/MATCH memerlukan Ctrl+Shift+Enter?
Formula menggunakan ISNUMBER(SEARCH(...)) untuk memeriksa semua baris keyword secara bersamaan, yang memerlukan evaluasi array. Tanpa Ctrl+Shift+Enter (atau pembungkus ARRAYFORMULA eksplisit), Sheets mengevaluasinya sebagai operasi skalar terhadap hanya baris pertama tabel Rules. Dalam praktik: jika pengkategorisasi Anda mengembalikan hanya kategori pertama untuk setiap vendor, berarti Anda lupa memasukkannya sebagai formula array.
Berapa banyak baris yang harus saya perpanjang formulanya?
Perpanjang formula Expenses Anda ke 5.000 baris jika Anda beroperasi sendiri; 20.000 jika Anda menarik dari beberapa sumber atau memproses satu tahun penuh sekaligus. Formula SUMIFS dan P&L bagaimanapun menggunakan rentang yang dibatasi, sehingga baris kosong di bagian bawah Expenses tidak mengembungkan total. Hindari memperpanjang ke 1.000.000 baris - referensi seluruh kolom pada set formula besar menyebabkan kalkulasi ulang lambat setiap kali ada pengeditan.
Bagaimana cara menangani vendor yang muncul dengan 5 varian string berbeda?
Tambahkan kelima varian sebagai baris terpisah di tabel Rules, masing-masing dipetakan ke Category yang sama. Jika variannya berbagi substring khas yang sama (misalnya, semuanya mengandung "STRIPE"), satu aturan dengan substring tersebut sudah mencakup semuanya. Jika tidak berbagi string umum, Anda membutuhkan satu baris per varian. Ini adalah hal yang wajar - payment processor dan sistem POS menghasilkan string vendor yang tidak konsisten, dan tabel rules yang kuat memperhitungkan hal itu alih-alih mencoba membersihkannya dari hulu.
Bisakah ini menangani pengeluaran dari beberapa mata uang?
Logika formula bersifat agnostik terhadap mata uang - ia mengkategorikan berdasarkan string vendor terlepas dari mata uang yang digunakan. Untuk pelacakan multi-mata uang, tambahkan kolom Currency di Expenses dan kolom FX_Rate yang mengonversi ke mata uang pelaporan Anda. SUMIFS di Summary harus mereferensikan kolom yang sudah dikonversi (=Amount * FX_Rate), bukan Amount mentah. Nilai tukar dapat diambil dengan =GOOGLEFINANCE("CURRENCY:USDIDR") untuk kurs langsung, atau di-hardcode untuk satu periode pelaporan.
Bagaimana agar tabel Rules tidak membengkak tak terkendali?
Audit secara triwulanan. Filter kolom Category untuk "Uncategorized" dan tambahkan aturan untuk vendor dengan pengeluaran di atas Rp 750.000/bulan yang masih belum terkategorikan. Hapus aturan untuk vendor yang tidak lagi Anda gunakan - aturan mati memperlambat pemindaian formula array tanpa alasan. Tabel rules yang dikelola dengan baik untuk operasi freelance tipikal berjumlah 30-80 baris; jika milik Anda mendekati 200, kemungkinan ada aturan yang tumpang tindih atau redundan yang bisa dikonsolidasikan.