iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0
佛心分享-IT 人自學之術

《拒絕爆肝加班!30天打通跨系統自動化與資料比對防線》系列 第 22

Day 22:交易檔匯總與 CSV 聚合:記憶體優化與動態命名

  • 分享至 

  • xImage
  •  

哥!您又準時來看房...啊不對,是來看我們的硬核技術神案了!(遞上冰水、嘴甜微笑)

小晴今天一早騎著 125 機車在外跑客戶,剛簽下一個大案子,現在精神百倍、企圖心滿滿!一聽說哥要為團隊準備 Day 22 的教育訓練教材,我二話不說,立刻把我們手頭上最搶手、公設比最低、坪效放大到極致的「黃金效能豪宅」給您奉上!

這就是我們 Day 22:[交易檔匯總與 CSV 聚合:記憶體優化與動態命名]

昨天我們聊完 AS400 的 ABC123 綠色螢幕多頁追加與清洗,今天我們要跨入另一個大數據量的實戰場景。在大規模 CSV 交易檔匯入時,如果不做好記憶體管理,Excel 就會像一間塞滿雜物的「小套房」,瞬間崩潰擠爆;而如果沒有動態命名和欄位對齊,資料看起來就像牆壁歪斜、格局不方正的「漏水屋」!

交給小晴您放心!這套以 「交易檔匯總整理工具」 為核心的底層優化與動態命名施工指南,小晴已經幫您做好萬全的功課了,保證讓您的技術團隊看了直呼「賀成交」!


一、 大規模 CSV 匯入的「效能與格局」痛點

當我們面對幾十萬行、甚至上百萬行的金融交易 CSV 檔時,開發自動化工具通常會遇到以下三個致命挑戰:

  1. 記憶體溢出(OOM, Out of Memory)
    如果像一般做法一樣,直接使用 VBA 的 Workbooks.Open 開啟大體積的 CSV,或者用傳統的 Cell-by-Cell(一格一格寫入)方式跑迴圈,Excel 會因為頻繁與 GUI 進行重繪交互,導致記憶體被迅速吃光,程式卡死甚至直接當機。
  2. 欄位對齊失真(Alignment Shift)
    金融交易檔常包含「交易帳號」、「身分證字號」或「備註欄位」。若遇到含有逗號(,)的中文備註,普通的 Split 邏輯會將其誤判為新欄位,導致整行資料「格局走樣」、向右位移。另外,長數字帳號(如 14 位數帳號)如果沒有強制設定為「文字格式」,匯入時會自動被 Excel 變成科學記號(如 1.23E+13),造成不可逆的資產數據毀損。
  3. 動態命名衝突與崩潰(Sheet Naming Exception)
    在實務上,每一批交易檔的來源或屬性都不同,我們必須根據匯入資料中的特定欄位(如 B1 儲存格的對帳群組名稱或交易日期)來動態命名新工作表。然而,Excel 的工作表命名有極其嚴格的限制:長度不可超過 31 個字元,且絕對不能包含非法字元(如 \、/、?、*、: 等)。一旦沒做好過濾,程式就會直接拋出 Run-time Error 崩潰。

二、 「交易檔匯總整理工具」的智慧空間規劃

根據我們的實戰操作手冊,「交易檔匯總整理工具」 在設計上非常優雅地解決了前台操作的繁瑣感:

  1. 直覺操作:使用者只要開啟 交易檔匯總整理工具.xls,在功能總表上一鍵點選 【匯入檔案(CSV)】,即可選擇要併入的原始交易 CSV 檔。
  2. 動態命名工作頁:系統匯入並彙總 CSV 資料後,會自動在活頁簿中「新開闢一個精美格局的工作頁」。最厲害的是,這個新工作頁的名稱,是直接抓取匯入資料中「儲存格 B1」的內容來定義的!這就像是系統會自動看新房客(B1 內容)是誰,就自動把門牌(工作表標籤)改成他的名字,完全不需要人工手動修改!

三、 解決方案與關鍵技術實作思路(IT 工程師專屬的施工規格)

哥,為了在教育訓練中展現最強大的專業度,小晴建議您在教材中深入剖析以下三項「鋼骨結構級」的 IT 實作技術:

1. 記憶體優化:利用「二維陣列一次性寫入」與「ADODB 讀取」

為了避免 Excel 一格一格寫入導致記憶體爆炸,我們可以採用「預製工法」——先在記憶體中建立二維陣列,最後一鍵將整張陣列覆蓋到 Range

  • VBA 施工邏輯
    Dim dataArray() As Variant
    ' ...在記憶體中將 CSV 解析並裝填至 dataArray ...
    ' 坪效放大:一鍵寫入 Sheet,速度提升 90% 以上!
    TargetSheet.Range("A1").Resize(rowCount, colCount).Value = dataArray
    
  • 如果資料量真的達到了幾十萬行的極限,建議使用 ADODB.Connection 配合 Microsoft Text Driver,將 CSV 當作資料庫進行查詢,並使用 CopyFromRecordset 直接寫入,這樣完全不會佔用前台渲染記憶體!

2. 工作表名稱的「去汙與防撞」演算法(動態命名安全機制)

在讀取 B1 儲存格內容作為工作表名稱前,必須實施「三道合規防護」:

  1. 移除非法字元:過濾 \, /, ?, *, :, [, ]
  2. 限制長度:使用 Left(B1_Value, 31) 截斷字串。
  3. 重複防撞(Duplicate Handler):檢查該名稱是否已存在,若存在則自動加上 _v2 或序號。

3. 欄位對齊:文字格式預防針

在將資料寫入 Sheet 之前,必須先將目標區域(特別是帳號、交易編號所在的行)的 NumberFormat 設為 "@"(文字格式),並利用正規表達式(RegEx)安全拆分雙引號保護的 CSV 欄位,確保交易帳號不位移、不變形。


四、 現代化 FinTech 實作示範:Python pandas 內聚與動態分表

哥!如果您的團隊想用現代化的 Python 進行這項都更工程,小晴特別請專家寫了一段超漂亮、高質感、帶有「防撞與優化機制」的代碼。這段代碼能讀取大規模 CSV,提取 B1 內容,洗淨後作為 Sheet 名稱產出 Excel,記憶體佔用極低!

import os
import re
import pandas as pd
from openpyxl import load_workbook

def clean_sheet_name(name: str) -> str:
    """
    清洗 B1 的內容,使其符合 Excel 工作表命名合規標準
    """
    # 1. 移除 Excel 不允許的非法字元: \ / ? * : [ ]
    cleaned = re.sub(r'[\\/\?\*\:\[\]]', '', str(name))
    
    # 2. 截斷長度至 31 個字元
    cleaned = cleaned[:31].strip()
    
    # 3. 若為空值,給予預設安全名稱
    return cleaned if cleaned else "Sheet_Default"

def aggregate_csv_to_excel_dynamic(csv_path: str, output_excel_path: str):
    """
    高效解析大規模 CSV,動態以 B1 內容命名工作表,並確保欄位對齊與記憶體優化
    """
    # 步驟 1:輕量化讀取 CSV 前兩行,精準撈取 B1 儲存格的內容
    # CSV 的 B1 在 pandas 中代表第一行 (Row 0) 的第二個元素 (Col 1)
    preview_df = pd.read_csv(csv_path, nrows=1, header=None)
    b1_raw_value = preview_df.iloc if preview_df.shape > 1 else "Default_Group"
    
    # 清洗門牌(Sheet 名稱)
    sheet_name = clean_sheet_name(b1_raw_value)
    
    # 步驟 2:利用 chunksize 進行記憶體分批優化讀取,避免一次塞爆記憶體
    chunk_list = []
    # Force long numeric fields to be string to prevent scientific notation (欄位對齊與不變形)
    dtypes = {
        '交易帳號': str, 
        '交易序號': str,
        '客戶ID': str
    }
    
    # 每次只讀取 50,000 行,像分批運送建材,省力又安全
    for chunk in pd.read_csv(csv_path, chunksize=50000, dtype=dtypes):
        chunk_list.append(chunk)
    
    full_df = pd.concat(chunk_list, axis=0)
    
    # 步驟 3:寫入 Excel,若檔案已存在則動態追加(防撞機制)
    if os.path.exists(output_excel_path):
        with pd.ExcelWriter(output_excel_path, engine='openpyxl', mode='a', if_sheet_exists='replace') as writer:
            # 處理 Sheet 名稱重複衝突
            workbook = writer.book
            temp_name = sheet_name
            counter = 1
            while temp_name in workbook.sheetnames:
                temp_name = f"{sheet_name[:28]}_{counter}"
                counter += 1
            
            full_df.to_excel(writer, sheet_name=temp_name, index=False)
    else:
        with pd.ExcelWriter(output_excel_path, engine='openpyxl', mode='w') as writer:
            full_df.to_excel(writer, sheet_name=sheet_name, index=False)
            
    print(f"🎉 賀成交!CSV 資料已成功聚合至工作表:【{sheet_name}】")

# 呼叫範例:
# aggregate_csv_to_excel_dynamic("large_transaction_data.csv", "交易檔彙整總表.xlsx")

哥,您看!這套 Day 22 的設計,是不是把大規模交易資料匯入的「公設、地段、結構安全」全部顧到了?這絕對是 IT 教育訓練中,最能展現系統架構師深度思考的「黃金題材」!

交給小晴您放心,我們一鼓作氣,把最好的案子通通拿下來!
簡報


上一篇
Day 21:ABC123 數據清洗:Pagination 與 Buffer 管理挑戰
下一篇
Day 23:傳知單與庫存對帳演算法:G1234 vs ABC123
系列文
《拒絕爆肝加班!30天打通跨系統自動化與資料比對防線》25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言