One More Thing

Tuesday, December 24, 2024

JWT (JSON Web Token): Solusi untuk Autentikasi dan Otorisasi ?

December 24, 2024 Posted by nurmanx , , No comments

Di era digital saat ini, banyak aplikasi yang saling terhubung dan membutuhkan sistem keamanan yang kuat namun efisien. Salah satu teknologi yang banyak digunakan untuk kebutuhan autentikasi dan otorisasi adalah JWT atau JSON Web Token

 

 

 

 

 

 

 

Apa Itu JWT?

JWT (JSON Web Token) adalah format token yang digunakan untuk mengirim data secara aman antar sistem dalam bentuk objek JSON yang sudah ditandatangani secara digital. Token ini umumnya dipakai untuk proses login dan otorisasi akses pengguna.

 JWT terdiri dari tiga bagian:

  1. Header – berisi informasi tentang algoritma yang digunakan (misalnya HS256).

  2. Payload – memuat data atau klaim, seperti ID pengguna atau perannya.

  3. Signature – tanda tangan digital yang menjamin bahwa token tidak diubah-ubah.

     


 

 

 

 

 

Mengapa JWT Diperlukan?

Sebelum JWT populer, banyak sistem menggunakan metode session-based authentication. Artinya, setelah pengguna login, data sesi disimpan di server. Namun metode ini memiliki keterbatasan:

  • Sulit digunakan pada sistem terdistribusi atau berbasis microservices.

  • Tidak fleksibel untuk aplikasi modern seperti SPA (Single Page Application).

  • Butuh memori tambahan untuk menyimpan sesi.

JWT hadir sebagai solusi yang lebih ringan dan praktis. Token menyimpan semua informasi yang dibutuhkan, sehingga server tidak perlu menyimpan sesi. Sistem ini disebut stateless — cocok untuk aplikasi modern yang skalanya besar.


Kelebihan JWT Dibandingkan Metode Lain

  1. Tidak Bergantung pada Server (Stateless)
    Server tidak perlu menyimpan data sesi. Token bisa diverifikasi langsung menggunakan tanda tangan digital.

  2. Cocok untuk Sistem Terdistribusi
    Ideal digunakan di lingkungan microservices atau REST API.

  3. Format Ringan dan Mudah Ditangani
    JWT hanya berupa string yang bisa dikirim lewat HTTP header.

  4. Bisa Digunakan untuk Autentikasi dan Otorisasi
    Token dapat menyimpan peran pengguna, sehingga kontrol akses bisa dilakukan tanpa mengecek database.

  5. Mudah Digunakan di Berbagai Platform
    JWT adalah standar terbuka, dapat diimplementasikan di banyak bahasa pemrograman.


Keunggulan Utama JWT

Keunggulan terbesar JWT adalah kemampuannya untuk membawa informasi secara aman tanpa beban penyimpanan di sisi server. Token ini cocok digunakan di sistem yang butuh fleksibilitas tinggi dan bekerja lintas platform, seperti aplikasi mobile, frontend-backend terpisah, hingga layanan API.

JWT juga dapat diatur masa berlakunya (expired), serta bisa dikombinasikan dengan token refresh agar tetap aman meskipun token utama sudah habis masa aktifnya.

 

Apakah JWT Aman?

JWT menawarkan keamanan yang baik, asalkan digunakan dengan benar. Keamanannya didukung oleh:

  • Penggunaan algoritma kriptografi seperti HS256 atau RSA.

  • Penandatanganan digital untuk mencegah perubahan isi token.

  • Pengaturan masa berlaku token (exp) untuk mencegah penyalahgunaan.

Namun, ada hal-hal penting yang harus diperhatikan:

  • Selalu gunakan HTTPS untuk mengirim token.

  • Hindari menyimpan token di tempat yang mudah diakses oleh skrip berbahaya (seperti localStorage jika ada risiko XSS).

  • Pastikan sistem memverifikasi tanda tangan token dengan benar.

Dengan praktik yang benar, JWT bisa menjadi bagian penting dari sistem keamanan aplikasi Anda.

 

JWT bisa tidak aman karena mencantumkan terlalu banyak informasi sensitif di dalam payload-nya.

 


 

 

 

 

 

 

Masalah pada token tersebut:

  1. Menyimpan password dalam token
    Ini kesalahan fatal. Password seharusnya tidak pernah disimpan atau dikirim, apalagi dalam token.

  2. Terlalu banyak data pribadi
    Informasi seperti email, alamat rumah, nomor HP, dan kartu kredit tidak seharusnya berada di dalam JWT, apalagi jika hanya menggunakan signed JWT (bukan encrypted).

  3. Risiko token bocor
    Jika token ini sampai bocor (misalnya lewat header Authorization), maka seluruh informasi di dalamnya bisa dibaca oleh siapa saja, karena payload JWT bisa dengan mudah didekode oleh siapapun.

     

JWT dapat di-decode, misalnya menggunakan tools yag tersedia secara online seperti https://jwt.io/


 

 

 

 

 

 

 

 

 

 

 

 

 

Best Practice:

  1. Hanya sertakan informasi minimum yang dibutuhkan, seperti user_id dan role.

  2. Jangan pernah menyimpan password, data keuangan, atau informasi pribadi di payload.

  3. Jika memang perlu menyimpan data sensitif, gunakan JWE (JSON Web Encryption), bukan hanya JWS (JSON Web Signature)

 

JWT adalah solusi modern yang sangat berguna untuk proses autentikasi dan otorisasi di berbagai jenis aplikasi. Sifatnya yang ringan, fleksibel, dan aman menjadikannya pilihan utama dalam membangun sistem yang efisien dan mudah diskalakan. Meski begitu, penerapannya tetap harus mengikuti standar keamanan agar sistem tetap terlindungi dari risiko penyalahgunaan.

Meskipun sistem sudah menggunakan JWT untuk autentikasi, tetap penting untuk memastikan URL dan input pengguna terlindungi dari serangan seperti URL injection. JWT hanya mengamankan proses identitas dan otorisasi, namun tidak menggantikan kebutuhan validasi dan sanitasi input secara menyeluruh.

 

Sunday, December 01, 2024

Web Scraping Menggunakan PHP Simple Html DOM Parser

December 01, 2024 Posted by nurmanx , No comments

Web Crawling dan Web Scraping



 

 

 

Web Crawling

Definisi:
Web crawling adalah proses otomatis untuk menjelajahi halaman-halaman web dari satu link ke link lainnya, seperti cara kerja Googlebot saat mengindeks website.

Tujuan utama:
Mengumpulkan dan memetakan struktur website atau mengindeks konten web untuk keperluan pencarian atau analisis skala besar.

Contoh:
Mesin pencari seperti Google, Bing, atau DuckDuckGo menggunakan crawler untuk menjelajahi dan mengindeks semua halaman yang bisa mereka temukan di internet.

 

Web Scraping

Definisi:
Web scraping adalah proses mengambil data spesifik dari halaman web, biasanya dengan mem-parsing kontennya seperti HTML atau JSON.

Tujuan utama:
Mengambil informasi tertentu seperti harga produk, review, artikel berita, dll.

Contoh:

  • Mengambil daftar harga dari situs e-commerce
  • Mengambil informasi profil dari LinkedIn (dengan izin atau via API resmi)
  • Mengambil data berita terbaru dari situs berita

 

Pada saat request data, server dapat memberikan hasil berupa data dalam berbagai format, misalnya : html, pdf, xml, json atau format yang lainnya.

Jika data yang dihasilkan dalam format xml atau json, maka proses crawling data akan relatif lebih mudah. Namun bagaimana jika data yang dihasilkan berupa format html.

Contoh jika kita mengakses data Kurs Pajak melalui laman : https://fiskal.kemenkeu.go.id/informasi-publik/kurs-pajak . 




 

 

 

 

 

 

 

 

 

 

Jika dilihat source code tampilan tersebut berupa script html menggunakan tag <table></table>


 

 
PHP Simple HTML DOM Parser

PHP Simple HTML DOM Parser adalah sebuah parser dokumen HTML yang cepat, sederhana, dan andal untuk PHP. Perangkat lunak ini dikembangkan oleh S.C. Chen, berdasarkan HTML Parser untuk PHP 4 yang dibuat oleh Jose Solorzano. PHP Simple HTML DOM Parser mampu memproses berbagai dokumen HTML, termasuk dokumen-dokumen yang dianggap tidak valid menurut spesifikasi HTML. Perangkat lunak ini bersifat bebas dan didistribusikan di bawah lisensi MIT.

Untuk membuat kumpulan data dari file html seperti contoh tersebut, diperlukan langkah sebagai berikut:

  • Install PHP Server untuk menjalankan script PHP (Appserve, XAMPP, dll)
  • Download PHP Simple HTML DOM Parser (https://sourceforge.net/projects/simplehtmldom/)
  • Pelajari website target, terutama struktur HTML-nya, misalnya dengan contoh website Kurs Pajak tersebut, didapat informasi sebagai berikut
  1. Kurs pajak berlaku dalam kurun waktu 1 minggu-an
  2. Kurs pajak terbit pada hari rabu

Dari hasil analisis tersebut, maka diperlukan seluruh tanggal yang bertepatan pada hari Rabu, hal ini dapat mudah kita dapatkan menggunakan spreadsheet (excel). 

  • Jalankan script PHP sebagai berikut : 

<iframe src="https://carbon.now.sh/embed?bg=rgba%28171%2C+184%2C+195%2C+1%29&t=seti&wt=none&l=auto&width=680&ds=true&dsyoff=20px&dsblur=68px&wc=true&wa=true&pv=56px&ph=56px&ln=false&fl=1&fm=Hack&fs=14px&lh=133%25&si=false&es=2x&wm=false&code=%253C%253Fphp%250Ainclude%28%27simple_html_dom.php%27%29%253B%250Aset_time_limit%2860%29%253B%250A%2524tanggal%253Darray%28%25222022-11-30%2522%252C%25222022-12-07%2522%252C%25222022-12-14%2522%252C%25222022-12-21%2522%252C%25222022-12-28%2522%29%253B%250A%250A%2524j%253Dcount%28%2524tanggal%29%253B%250A%250Afor%28%2524i%253D0%253B%2524i%253C%2524j%253B%2524i%252B%252B%29%257B%250A%2524html%2520%253D%2520file_get_html%28%250A%2522https%253A%252F%252Ffiskal.kemenkeu.go.id%252Finformasi-publik%252Fkurs-pajak%253Fdate%253D%2524tanggal%255B%2524i%255D%2522%29%253B%250Aforeach%28%2524html-%253Efind%2520%28%27strong%27%29%2520as%2520%2524element%29%250A%2509%2509echo%28%2520%2524element%29%253B%2520%2520%2520%250Aforeach%28%2524html-%253Efind%2520%28%27p.text-muted%27%29%2520as%2520%2524element%29%250A%2509%2509echo%28%2520%2524element%29%253B%250Aforeach%28%2524html-%253Efind%2520%28%27table%27%29%2520as%2520%2524element%29%250A%2509%2509foreach%28%2524element%2520-%253Efind%28%27img%27%29%2520as%2520%2524item%29%2520%257B%2520%2524item-%253Eoutertext%2520%253D%2520%27%27%253B%2520%257D%250A%2509%2509%2524element-%253Esave%28%29%253B%250A%2509%2509echo%28%2520%2524element%29%2520.%2520%27%253Cbr%253E%27%253B%250A%257D%250A%253F%253E" style="width: 833px; height: 558px; border:0; transform: scale(1); overflow:hidden;" sandbox="allow-scripts allow-same-origin"> </iframe>

<?php
include ('simple_html_dom.php');
set_time_limit(60);
$tanggal = array(
    "2022-11-30",
    "2022-12-07",
    "2022-12-14",
    "2022-12-21",
    "2022-12-28"
);

$j = count($tanggal);

for ($i = 0;$i < $j;$i++)
{
    $html = file_get_html("https://fiskal.kemenkeu.go.id/informasi-publik/kurs-pajak?date=$tanggal[$i]");
    foreach ($html->find('strong') as $element) echo ($element);
    foreach ($html->find('p.text-muted') as $element) echo ($element);
    foreach ($html->find('table') as $element) foreach ($element->find('img') as $item)
    {
        $item->outertext = '';
    }
    $element->save();
    echo ($element) . '<br>';
}
?>
http://hilite.me/

Tampilan setelah scrip dijalankan:

 



 

 

 

 

 

 

 

 

 

 

Hasil crawling tersebut bisa diolah mengunakan spreadsehet (excel), hasilnya bisa di download di Database Kurs Pajak 2010 sd 2024.xlsx

Semoga Bermanfaat 😁

 

Thursday, November 21, 2024

Menghitung Persediaan Metode FIFO dengan Macro Excel

November 21, 2024 Posted by nurmanx , No comments

Metode FIFO (First In, First Out) merupakan metode pencatatan yang digunakan dalam mengelola persediaan. Sesuai namanya, FIFO mengasumsikan bahwa barang yang pertama kali dibeli adalah barang yang pertama kali dijual atau digunakan. Artinya, nilai persediaan akhir akan dihitung berdasarkan harga pembelian terbaru.


 

 

 

 

  

 

Metode ini cocok digunakan untuk bisnis yang menjual produk yang mudah basi atau cepat usang, seperti makanan, obat-obatan, atau barang elektronik. Selain itu, FIFO juga mencerminkan arus barang yang logis dan lebih realistis dalam kebanyakan proses distribusi.

Kesulitan Menghitung FIFO dengan Spreadsheet Biasa

Meskipun konsep FIFO terdengar sederhana, menghitungnya secara manual di spreadsheet seperti Excel bisa menjadi tantangan tersendiri, terutama ketika volume transaksi tinggi dan terdiri dari banyak jenis barang. Beberapa kendala umum antara lain:

  • Pengurutan kronologis transaksi masuk dan keluar: Setiap pembelian dan penjualan harus diurutkan berdasarkan tanggal agar urutan FIFO tetap konsisten.

  • Pencocokan jumlah barang yang dijual dengan pembelian yang relevan: Penjualan harus "menghabiskan" pembelian secara berurutan, dan sisa dari pembelian sebelumnya harus dilacak.

  • Kesalahan manusia: Proses manual rawan kesalahan terutama jika tidak menggunakan formula dinamis atau pencatatan terstruktur.

  • Waktu pengerjaan yang lama: Untuk perusahaan dengan ratusan transaksi per bulan, menghitung FIFO secara manual bisa memakan waktu berjam-jam.

Solusi: Menggunakan Macro Excel untuk FIFO

Salah satu solusi efektif untuk mengatasi kompleksitas ini adalah dengan menggunakan Macro (VBA) di Excel. Macro memungkinkan pengguna untuk mengotomatiskan proses pencocokan pembelian dan penjualan berdasarkan logika FIFO.

Scipt yang digunakan adalah sebagai berikut:

 

Option Base 1
Sub FIFO()
'
Dim QtySold() As Long, SKU_TYPE() As String, SalesINV() As String, source() As String, Cost() As Double
Dim i As Integer, t As Integer, pending As Integer, matched As Integer, j As Integer, x As Double
Dim rngA As Range
Dim cell As Range


' www.excel4routine.com
' ZKL 13/04/19
    Application.ScreenUpdating = False

Worksheets("Inventory").Range("F2:H1000000").Clear
Worksheets("Inventory").Range("N2:P1000000").Clear
Worksheets("LOG").Range("A2:F1000000").Clear

        'if inventory records < 1 row exit sub
        'else add remaining column fill down
        With ActiveSheet
            If .Cells(.Rows.Count, "A").End(xlUp).Row > 2 Then
            
                'Sort Inventory by Pdt,by Date
                'https://trumpexcel.com/sort-data-vba/
                With ActiveSheet.Sort
                    .SortFields.Clear ' to clear prior sort data
                    .SortFields.Add Key:=Range("B1"), Order:=xlAscending
                    .SortFields.Add Key:=Range("A1"), Order:=xlAscending
                    .SetRange Range("mydata")
                    .Header = xlYes
                    .Apply
                End With
            
                .Range("G2:G" & .Cells(.Rows.Count, "C").End(xlUp).Row).Formula = "=C2-F2"
                .Range("H2:H" & .Cells(.Rows.Count, "C").End(xlUp).Row).Formula = "=G2*D2"
                .Range("O2:O" & .Cells(.Rows.Count, "K").End(xlUp).Row).Formula = "=SUMIFs(LOG!F:F,LOG!A:A,K2,LOG!C:C,L2)"
            End If
             
        End With
        

        
        
        
        'Check Availability of stock for those pending insufficient cases

        Set rngA = ActiveSheet.Range("P2:P" & ActiveSheet.Cells(ActiveSheet.Rows.Count, "P").End(xlUp).Row)
        
        t = 0
        
        For Each cell In rngA
            If cell.Value = "Insufficient Stock" Then
                
                If Not WorksheetFunction.SumIf(ActiveSheet.Range("B:B"), ActiveSheet.Range("L" & cell.Row).Value, ActiveSheet.Range("G:G")) < ActiveSheet.Range("M" & cell.Row).Value Then
                    ActiveSheet.Range("N" & cell.Row).Value = ActiveSheet.Range("M" & cell.Row).Value
                    ActiveSheet.Range("P" & cell.Row).ClearContents
                    'Narrow down the range for SKU lookup
                    'goto by find
                    Let endrow = Columns("B:B").Find(What:=ActiveSheet.Range("L" & cell.Row).Value, After:=ActiveSheet.Range("B1"), LookIn:=xlValues, LookAt _
                            :=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:= _
                            False, SearchFormat:=False).Row
                    Let startrow = Columns("B:B").Find(What:=ActiveSheet.Range("L" & cell.Row).Value, After:=ActiveSheet.Range("B1"), LookIn:=xlValues, LookAt _
                            :=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
                            False, SearchFormat:=False).Row
                            
                    x = ActiveSheet.Range("M" & cell.Row).Value
                       
                    'Loop through Inventory
                    For i = startrow To endrow
                                 
                        With Range("B" & i)
                                
                            If x <> 0 And .Offset(, 5).Value > 0 Then
                                t = t + 1
                                ReDim Preserve QtySold(t)
                                ReDim Preserve SKU_TYPE(t) 'Range("L" & j).Value
                                ReDim Preserve SalesINV(t) 'Range("K" & j).Value
                                ReDim Preserve source(t)    '.Offset(, 3)
                                ReDim Preserve Cost(t)    '.Offset(, 2)
                                    
                                    If .Offset(, 5).Value >= x Then
                                        .Offset(, 4) = .Offset(, 4) + x
                                        QtySold(t) = x
                                        SKU_TYPE(t) = ActiveSheet.Range("L" & cell.Row).Value
                                        SalesINV(t) = ActiveSheet.Range("K" & cell.Row).Value
                                        source(t) = .Offset(, 3)
                                        Cost(t) = .Offset(, 2)
                                        x = 0
                                    Else
                                        SKU_TYPE(t) = ActiveSheet.Range("L" & cell.Row).Value
                                        SalesINV(t) = ActiveSheet.Range("K" & cell.Row).Value
                                        source(t) = .Offset(, 3)
                                        Cost(t) = .Offset(, 2)
                                        QtySold(t) = .Offset(, 5).Value
                                        x = x - .Offset(, 5).Value
                                        .Offset(, 4) = .Offset(, 4) + .Offset(, 5)
                                    End If
                            End If
                                   
                        End With
                        
                    Next i
                    
                End If
            End If
        Next cell
        

    'Do a check for new orders pending to be matched comparing the last row of col M & N
        Let pending = Columns("M:M").Find(What:="*", After:=ActiveSheet.Range("M1"), LookIn:=xlFormulas, LookAt _
        :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:= _
        False, SearchFormat:=False).Row
        
        Let matched = Columns("N:N").Find(What:="*", After:=ActiveSheet.Range("N1"), LookIn:=xlFormulas, LookAt _
        :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:= _
        False, SearchFormat:=False).Row
        
        
    'Do a check for availability of remaining inventory b4 going on
    'Loop through sales order .if stock available proceed to match else just 0 and skip to next iteration
        For j = matched + 1 To pending
            
            If WorksheetFunction.SumIf(ActiveSheet.Range("B:B"), ActiveSheet.Range("L" & j).Value, ActiveSheet.Range("G:G")) < ActiveSheet.Range("M" & j).Value Then
                Range("N" & j).Value = 0
                Range("P" & j).Value = "Stock tidak mencukupi" 'Update those outstanding "insufficient stocks" that are just matched to LOG
                GoTo NextIteration:
            Else
                Range("N" & j).Value = Range("M" & j).Value
            End If


        'Narrow down the range for SKU lookup
        'goto by find
            Let endrow = Columns("B:B").Find(What:=ActiveSheet.Range("L" & j).Value, After:=ActiveSheet.Range("B1"), LookIn:=xlValues, LookAt _
                    :=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:= _
                    False, SearchFormat:=False).Row
            Let startrow = Columns("B:B").Find(What:=ActiveSheet.Range("L" & j).Value, After:=ActiveSheet.Range("B1"), LookIn:=xlValues, LookAt _
                    :=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
                    False, SearchFormat:=False).Row
                    
            x = ActiveSheet.Range("M" & j).Value

            
            'Loop through Inventory
            For i = startrow To endrow
                         
                With Range("B" & i)
                        
                    If x <> 0 And .Offset(, 5).Value > 0 Then
                            
                        t = t + 1
                        ReDim Preserve QtySold(t)
                        ReDim Preserve SKU_TYPE(t) 'Range("L" & j).Value
                        ReDim Preserve SalesINV(t) 'Range("K" & j).Value
                        ReDim Preserve source(t)    '.Offset(, 3)
                        ReDim Preserve Cost(t)    '.Offset(, 2)
                            
                            If .Offset(, 5).Value >= x Then
                                .Offset(, 4) = .Offset(, 4) + x
                                QtySold(t) = x
                                SKU_TYPE(t) = ActiveSheet.Range("L" & j).Value
                                SalesINV(t) = ActiveSheet.Range("K" & j).Value
                                source(t) = .Offset(, 3)
                                Cost(t) = .Offset(, 2)
                                x = 0
                            Else
                                SKU_TYPE(t) = ActiveSheet.Range("L" & j).Value
                                SalesINV(t) = ActiveSheet.Range("K" & j).Value
                                source(t) = .Offset(, 3)
                                Cost(t) = .Offset(, 2)
                                QtySold(t) = .Offset(, 5).Value
                                x = x - .Offset(, 5).Value
                                .Offset(, 4) = .Offset(, 4) + .Offset(, 5)
                            End If
                    
                    End If
                                               
                End With
                
            Next i
NextIteration:
        Next j
        
        'UPDATE LOG
        On Error Resume Next
        'http://www.cpearson.com/excel/ArraysAndRanges.aspx
        'Could be improved through split function I think....to be explored later
        Dim Destination As Range
        
        Set Destination = LOG.Cells(LOG.Rows.Count, "A").End(xlUp).Offset(1, 0)
        Set Destination = Destination.Resize(UBound(SalesINV), 1)
        Destination.Value = Application.Transpose(SalesINV)
        
        Set Destination = LOG.Cells(LOG.Rows.Count, "B").End(xlUp).Offset(1, 0)
        Set Destination = Destination.Resize(UBound(source), 1)
        Destination.Value = Application.Transpose(source)
        
        Set Destination = LOG.Cells(LOG.Rows.Count, "C").End(xlUp).Offset(1, 0)
        Set Destination = Destination.Resize(UBound(SKU_TYPE), 1)
        Destination.Value = Application.Transpose(SKU_TYPE)
        
        Set Destination = LOG.Cells(LOG.Rows.Count, "D").End(xlUp).Offset(1, 0)
        Set Destination = Destination.Resize(UBound(QtySold), 1)
        Destination.Value = Application.Transpose(QtySold)
        
        Set Destination = LOG.Cells(LOG.Rows.Count, "E").End(xlUp).Offset(1, 0)
        Set Destination = Destination.Resize(UBound(Cost), 1)
        Destination.Value = Application.Transpose(Cost)
        
        LOG.Range("F2:F" & LOG.Cells(LOG.Rows.Count, "E").End(xlUp).Row).Formula = "=E2*D2"
        '''''End If
        
        With ActiveSheet
            .Range("Orders").Value = .Range("Orders").Value
            .Range("MyData").Value = .Range("MyData").Value
        End With
        DoEvents

    Application.ScreenUpdating = True
End Sub

 

Langkah-langkah penggunaan script tersebut yaitu:

1. Input data persediaan pada kolom dengan warna biru muda


 2. Input rincian pengeluaran barang pada kolom dengan warna kuning muda


 

 

 

 

 

 

 

 

 

3. Klik tombol "Click for FIFO Matching"

4. Hasil perhitungan FIFO akan secara otomatis muncul di kolom dengan warna biru tua dan kuning tua.

 

Bagi anda yang tidak mau pusing dengan script, sudah saya sediakan file yang bisa di download di Macro Excel - Persediaan FIFO.xlsm 

Selamat mencoba 😁

Wednesday, October 09, 2024

Ekstraksi Nomor Referensi Dari Teks Tidak Beraturan

October 09, 2024 Posted by nurmanx , No comments

Ekstraksi nomor referensi dari suatu teks, diperlukan untuk mendapatkan nomor tertentu sehingga dapat digunakan untuk pengolahan data berikutnya, misalnya untuk dilakukan VLOOKUP ke data lain. Kendala yang sering muncul yaitu posisi nomor referensi tersebut tidak seragam pada suatu teks, sehingga kita tidak dapat menggunakan formula MID biasa.



 


 

 

 

 

 

Contoh teks yang mengandung informasi nomor referensi yaitu :

1. 982688811392 - JKL6218 ###>?+ INV.36301 @@ 88.6003
2. 982688811889 - JKL4953 ### INV.64576 @@ 88.8515

Pada contoh tersebut, posisi nomor referensi (INV) tidak seragam antara contoh nomor 1 dan nomor 2. Untuk itu, kita perlu menggunakan formula MID yang digabungkan dengan formula SEARCH.

Formula  MID

Formula MID mengembalikan jumlah karakter tertentu dari sebuah string teks, dimulai dari posisi yang Anda tentukan, berdasarkan jumlah karakter yang Anda tentukan.

Syntaks :

MID(text, start_num, num_chars)

Formula MID memiliki argumen berikut:

  • text : String teks yang memuat karakter yang ingin Anda ekstrak.
  • start_num : Posisi karakter pertama yang ingin Anda ekstrak dalam teks. Karakter pertama dalam teks memiliki start_num 1, dan seterusnya.
  • num_chars : Menentukan jumlah karakter yang ingin dikembalikan oleh MID.

Formula  SEARCH

Formula SEARCH menemukan satu string teks dalam string teks kedua, dan mengembalikan nomor posisi awal string teks pertama dari karakter pertama string teks kedua. Sebagai contoh, untuk menemukan posisi huruf "n" di kata "printer", Anda bisa menggunakan fungsi ini:

=SEARCH("n","printer")

Formula ini mengembalikan 4 karena "n" adalah karakter keempat dalam kata "printer."

Sintaks

SEARCH(find_text,within_text,[start_num])

Formula SEARCH memiliki argumen berikut:

  • find_text : Teks yang ingin Anda temukan.
  • within_text : Teks yang di dalamnya Anda ingin mencari nilai dari argumen find_text.
  • start_num : Nomor karakter dalam argumen within_text di mana Anda ingin memulai pencarian.

Contoh penggunaan formula MID yang digabungkan dengan formula SEARCH yaitu :


Contoh spreadsheet dapat dilihat di : Esktraksi Nomor Referensi Dari Teks

Semoga Bermanfaat 😀