
難度
初階
所需時間
45–60 分鐘(不計大型資料跑批)
你需要準備
Google Forms · Google Sheets · Microsoft Excel 桌面版(Windows 或 Mac) · ChatGPT · Visual Basic Editor · VBA · Power Query(可選替代方案)
開始之前
- 擁有表單及回應試算表的合法存取權,並清楚哪些同事仍可存取連結的 Google Sheet
- 已安裝 Microsoft Excel 桌面版;Excel 網頁版不能建立、執行或編輯 VBA
- 準備一份只含虛構資料的測試副本,不在唯一一份正式回應檔首次執行
- 知道複選欄的精確標題,以及匯出檔實際使用的分隔符號
- 已確認公司允許使用 ChatGPT、VBA 及處理相關個人資料
Google 表單很適合收集課程、活動、義工或服務報名,但只要問題類型是「核取方塊」,同一位填表者選了三個項目,匯出到試算表後通常仍是一列、一個儲存格、三個答案。人眼看得懂,Excel 的篩選、樞紐分析、名額統計和下游匯入卻很難直接使用。
本教學會把資料正規化成清楚的規則:一位填表者 × 一個選項 = 一個輸出列。例如「陳同學/課程 A、課程 C」會變成「陳同學/課程 A」和「陳同學/課程 C」兩列;時間戳記、聯絡欄等資料隨每個選項重複,而原始回應表完全不改。
所有畫面均使用虛構資料並移除帳戶、人物、作者、頻道、社交平台及宣傳識別。你也應只用測試副本跟做,不要把正式姓名、電郵、電話或完整報名名單交給 AI。
結果先行:本文提供的巨集不讀瀏覽器、不登入 Google、不上載 Excel、不寄信,也不操作外部檔案。它只讀取目前含巨集活頁簿內明確命名的來源表,完成驗證後重建一張明確命名的輸出表。
先看清楚輸入與輸出
| 資料層 | 每列代表甚麼 | 「報名課程」例子 | 用途 |
|---|---|---|---|
| Google 表單原始回應 | 一次提交 | 課程 A, 課程 C | 保留提交紀錄 |
| 本文輸出 | 一位填表者的一個選項 | 第一列:課程 A 第二列:課程 C | 篩選、統計、名單分組、匯入 |

Google 的問題類型說明確認核取方塊可多選。本文不是把三個選項拆成三欄,而是拆成三列,因為逐列結構更適合樞紐分析、每班人數、郵件合併和資料庫匯入。
完整流程:由表單到可驗收名單
- 確認表單問題、回應目的地和存取權。
- 在 Google Sheets 檢查欄名、複選內容和真正分隔符。
- 下載 Excel 副本,保留一份不含巨集的原始備份。
- 把來源頁籤命名為「表單回應」,另存測試用 .xlsm。
- 只把資料結構和虛構樣本寫成 ChatGPT 提示詞。
- 審查 VBA,再貼入標準 Module 並編譯。
- 執行巨集,讓結果寫入「輸出」。
- 核對總選項數、抽樣、空白、錯誤和重跑結果。
步驟一:先確認表單和試算表的存取邊界
在 Google Forms 的 Responses/回應分頁,可進入連結的 Google Sheet。Google 的回應管理說明亦提醒:表單協作者可能同時擁有連結試算表的權限,而移除表單協作者不等於自動移除試算表權限。處理報名個人資料前,要分別檢查兩邊的分享名單。

如果你只需要一次下載,Google 亦提供回應 CSV;本文沿用 Excel 工作流程,因為稍後要在桌面 Excel 執行 VBA。無論用 Sheet、CSV 或 XLSX,先把取得日期、表單版本和資料擁有人記錄在案。
步驟二:檢查欄名、資料列和分隔符

請逐項記錄以下規格,之後提示 AI 和驗收都會用到:
- 來源工作表:本文統一命名為「表單回應」。
- 標題列:第一列,且複選欄精確標題是「報名課程」。
- 資料起點:第二列;不要假設固定有 100 或 1,000 列。
- 分隔符:雙擊儲存格並複製到純文字編輯器,確認是半形逗號、全形逗號、分號還是換行。
- 空白規則:沒有選項的提交不產生輸出列,但來源仍保留。
- 重複規則:本文不靜默去重;若同一來源列真的重複「課程 A」,輸出也重複,讓負責人決定如何修正。
| 來源「報名課程」 | 預期輸出列數 | 備註 |
|---|---|---|
| 課程 A, 課程 B | 2 | 半形逗號 |
| 課程 A,課程 C | 2 | 全形逗號 |
| 課程 B;課程 D | 2 | 全形分號 |
| 課程 A 課程 B | 2 | 儲存格內換行 |
| 課程 A,, 課程 C | 2 | 空項略過 |
| 空白 | 0 | 來源列不刪除,只是不輸出 |
重要限制:若選項本身也可以含逗號,例如 Other/其他的自由文字是「Python, Excel」,純文字已無法分辨哪個逗號是答案、哪個是分隔符。不要用猜測修補;應限制選項字元、把自由文字放另一欄,或從保留結構的來源重新取得資料。
步驟三:下載 Excel 副本並固定測試環境
- 在 Google Sheets 選 File/檔案 → Download/下載 → Microsoft Excel (.xlsx)。
- 把原始下載檔改成容易辨認的備份,例如
course-registration_RAW_20260721.xlsx,不要在它執行巨集。 - 複製成
course-registration_TEST_20260721.xlsx,再用 Excel 桌面版開啟這份 TEST 副本。 - 在 Excel 選 File → Save As,檔案類型選 Excel Macro-Enabled Workbook (*.xlsm),另存為
course-registration_TEST_20260721.xlsm;不要只在 Finder 或 File Explorer 改副檔名,否則內容格式與副檔名會不一致。 - 在 .xlsm 測試檔把來源頁籤精確命名為「表單回應」。
- 只保留 8–20 列虛構或已適當匿名化的測試資料,覆蓋正常、空白、混合分隔符和異常值。
要保留 VBA,檔案必須使用支援巨集的格式。Microsoft 的儲存巨集說明建議另存為 Excel Macro-Enabled Workbook(.xlsm);一般 .xlsx 不會保留 VBA。
步驟四:不要上載名單,只把規格交給 ChatGPT

直接說「幫我拆分 Excel」會留下太多猜測。以下提示詞把讀取範圍、輸出定義、錯誤條件和禁止行為寫清楚,可直接複製後按你的虛構結構修改:
你是資深 Microsoft Excel VBA 工程師。請只根據以下虛構結構撰寫可在 Excel 桌面版執行的 VBA,不要要求我上載真實活頁簿。
目標:把 Google 表單核取方塊匯出的複選答案,由「一位填表者一列、所有選項同一格」正規化為「一位填表者 × 一個選項一列」。
活頁簿與欄位:
- 只操作 ThisWorkbook。
- 來源工作表名稱:表單回應。
- 輸出工作表名稱:輸出。
- 第一列是標題。
- 複選欄標題:報名課程。
- 其他欄位可能包括時間戳記、姓名、電郵、電話;輸出時要逐列原樣重複,但來源工作表不可被修改。
分隔與清理規則:
- 支援半形逗號、全形逗號、半形分號、全形分號、CRLF、CR 或 LF。
- 去除每個選項前後空格,略過空白項目。
- 不可靜默去除重複選項;若來源重複,輸出也保留,方便人工追查。
安全與穩定要求:
1. 第一行使用 Option Explicit,所有變數完整宣告。
2. 使用 ThisWorkbook.Worksheets("表單回應"),不可使用 ActiveSheet、Selection 或 Select。
3. 用 Find("*") 找整張來源表真正最後一列及最後一欄,不可只依賴固定欄。
4. 先確認來源表、標題與資料存在;若「報名課程」標題重複,要停止並清楚報錯。
5. 先在記憶體完成計數和輸出陣列;所有驗證通過後才建立或清空「輸出」。
6. 「輸出」不存在便建立,存在便只清空該輸出表;不可刪除來源或其他工作表。
7. 每個輸出列保留全部來源欄位,只把「報名課程」改成單一選項。
8. 防止以 =、+、-、@ 開頭的文字在輸出時被當成公式;數字和日期仍保留為值。
9. 檢查輸出列數不超過 Excel 工作表上限,加入完整錯誤處理,還原 ScreenUpdating、EnableEvents 和 Calculation。
10. 不准使用 Shell、Kill、FileSystemObject、HTTP、電郵、自動開啟事件或任何外部連線。
交付格式:
- 先用 8 點解釋讀取、寫入、停止條件及重跑行為。
- 提供可直接貼入「標準 Module」的完整程式碼。
- 最後提供正常、混合分隔符、空白、錯誤值、重複標題、重跑及列數核對的測試清單。
- 不要聲稱程式碼毋須測試。
模型名稱和 ChatGPT 介面會改變,重點不是選一個舊版本,而是把可驗收規格寫完整。AI 回覆仍是未受信任的程式碼草稿;逐行審查、測試副本和人工驗收都不能省略。
步驟五:使用這個可重跑、保留來源的 VBA
以下版本把整份來源讀入記憶體,第一遍只驗證及計數,第二遍建立輸出陣列;所有驗證通過後,才建立或清空「輸出」。這比一邊讀、一邊逐列刪寫更容易控制失敗狀態,也較適合數千列資料。
Option Explicit
Private Const SOURCE_SHEET As String = "表單回應"
Private Const OUTPUT_SHEET As String = "輸出"
Private Const CHOICE_HEADER As String = "報名課程"
Public Sub SplitCheckboxResponses()
Dim wb As Workbook
Dim wsSource As Worksheet
Dim wsOutput As Worksheet
Dim sourceData As Variant
Dim outputData() As Variant
Dim choices As Variant
Dim choiceValue As String
Dim lastRow As Long
Dim lastCol As Long
Dim choiceCol As Long
Dim sourceRow As Long
Dim outputRow As Long
Dim outputRowCount As Long
Dim choiceIndex As Long
Dim colIndex As Long
Dim previousCalculation As XlCalculation
Dim previousScreenUpdating As Boolean
Dim previousEnableEvents As Boolean
Dim settingsCaptured As Boolean
Dim successMessage As String
Dim errorMessage As String
On Error GoTo HandleError
Set wb = ThisWorkbook
previousCalculation = Application.Calculation
previousScreenUpdating = Application.ScreenUpdating
previousEnableEvents = Application.EnableEvents
settingsCaptured = True
If StrComp(SOURCE_SHEET, OUTPUT_SHEET, vbTextCompare) = 0 Then
Err.Raise vbObjectError + 1000, , _
"來源工作表與輸出工作表不可同名。"
End If
Set wsSource = GetRequiredWorksheet(wb, SOURCE_SHEET)
lastRow = LastUsedRow(wsSource)
lastCol = LastUsedColumn(wsSource)
If lastRow < 2 Or lastCol < 1 Then
Err.Raise vbObjectError + 1001, , _
"來源工作表沒有標題及至少一列資料。"
End If
choiceCol = FindUniqueHeaderColumn(wsSource, CHOICE_HEADER, lastCol)
sourceData = wsSource.Range( _
wsSource.Cells(1, 1), _
wsSource.Cells(lastRow, lastCol) _
).Value2
' 第一遍只驗證及計算輸出列數,不修改任何工作表。
outputRowCount = 1
For sourceRow = 2 To UBound(sourceData, 1)
If IsError(sourceData(sourceRow, choiceCol)) Then
Err.Raise vbObjectError + 1002, , _
"來源第 " & sourceRow & " 列的「" & CHOICE_HEADER & _
"」是 Excel 錯誤值,請先修正。"
End If
choices = SplitChoices(CStr(sourceData(sourceRow, choiceCol)))
For choiceIndex = LBound(choices) To UBound(choices)
choiceValue = CleanChoice(CStr(choices(choiceIndex)))
If Len(choiceValue) > 0 Then
If outputRowCount = wsSource.Rows.Count Then
Err.Raise vbObjectError + 1004, , _
"拆分結果超過此 Excel 工作表的列數上限。"
End If
outputRowCount = outputRowCount + 1
End If
Next choiceIndex
Next sourceRow
If outputRowCount = 1 Then
Err.Raise vbObjectError + 1003, , _
"找不到任何非空白的複選答案,輸出工作表未被修改。"
End If
If outputRowCount > wsSource.Rows.Count Then
Err.Raise vbObjectError + 1004, , _
"拆分後需要 " & outputRowCount & _
" 列,超過此 Excel 工作表的列數上限。"
End If
ReDim outputData(1 To outputRowCount, 1 To lastCol)
For colIndex = 1 To lastCol
outputData(1, colIndex) = SafeOutputValue(sourceData(1, colIndex))
Next colIndex
' 第二遍建立輸出陣列:每個非空白選項各佔一列。
outputRow = 1
For sourceRow = 2 To UBound(sourceData, 1)
choices = SplitChoices(CStr(sourceData(sourceRow, choiceCol)))
For choiceIndex = LBound(choices) To UBound(choices)
choiceValue = CleanChoice(CStr(choices(choiceIndex)))
If Len(choiceValue) > 0 Then
outputRow = outputRow + 1
For colIndex = 1 To lastCol
outputData(outputRow, colIndex) = _
SafeOutputValue(sourceData(sourceRow, colIndex))
Next colIndex
outputData(outputRow, choiceCol) = SafeOutputValue(choiceValue)
End If
Next choiceIndex
Next sourceRow
' 到這裏所有輸入已通過驗證,才建立或清空輸出工作表。
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Set wsOutput = GetOrCreateOutputWorksheet(wb, wsSource, OUTPUT_SHEET)
If wsOutput.AutoFilterMode Then wsOutput.AutoFilterMode = False
wsOutput.Cells.Clear
With wsOutput.Range( _
wsOutput.Cells(1, 1), _
wsOutput.Cells(outputRowCount, lastCol) _
)
.Value2 = outputData
.AutoFilter
End With
wsOutput.Rows(1).Font.Bold = True
For colIndex = 1 To lastCol
wsOutput.Columns(colIndex).NumberFormat = _
wsSource.Cells(2, colIndex).NumberFormat
wsOutput.Columns(colIndex).AutoFit
If wsOutput.Columns(colIndex).ColumnWidth > 50 Then
wsOutput.Columns(colIndex).ColumnWidth = 50
End If
Next colIndex
successMessage = _
"完成:讀取 " & (lastRow - 1) & " 個來源列,輸出 " & _
(outputRowCount - 1) & " 個『填表者 × 選項』資料列。" & vbCrLf & _
"來源工作表沒有被修改。請立即按驗收清單抽查。"
CleanExit:
On Error Resume Next
If settingsCaptured Then
Application.Calculation = previousCalculation
Application.EnableEvents = previousEnableEvents
Application.ScreenUpdating = previousScreenUpdating
End If
On Error GoTo 0
If Len(errorMessage) > 0 Then
MsgBox errorMessage, vbCritical, "拆分未完成"
ElseIf Len(successMessage) > 0 Then
MsgBox successMessage, vbInformation, "拆分完成"
End If
Exit Sub
HandleError:
errorMessage = _
"錯誤 " & Err.Number & ": " & Err.Description & vbCrLf & _
"來源工作表不應被修改;請核對工作表名、欄名及測試資料。"
Resume CleanExit
End Sub
Private Function GetRequiredWorksheet( _
ByVal wb As Workbook, _
ByVal sheetName As String _
) As Worksheet
On Error Resume Next
Set GetRequiredWorksheet = wb.Worksheets(sheetName)
On Error GoTo 0
If GetRequiredWorksheet Is Nothing Then
Err.Raise vbObjectError + 1010, , _
"找不到來源工作表「" & sheetName & "」。"
End If
End Function
Private Function GetOrCreateOutputWorksheet( _
ByVal wb As Workbook, _
ByVal wsSource As Worksheet, _
ByVal sheetName As String _
) As Worksheet
On Error Resume Next
Set GetOrCreateOutputWorksheet = wb.Worksheets(sheetName)
On Error GoTo 0
If GetOrCreateOutputWorksheet Is Nothing Then
Set GetOrCreateOutputWorksheet = _
wb.Worksheets.Add(After:=wsSource)
GetOrCreateOutputWorksheet.Name = sheetName
End If
End Function
Private Function FindUniqueHeaderColumn( _
ByVal ws As Worksheet, _
ByVal expectedHeader As String, _
ByVal lastCol As Long _
) As Long
Dim colIndex As Long
Dim foundColumn As Long
Dim headerValue As String
For colIndex = 1 To lastCol
If Not IsError(ws.Cells(1, colIndex).Value2) Then
headerValue = CleanChoice(CStr(ws.Cells(1, colIndex).Value2))
If StrComp(headerValue, expectedHeader, vbTextCompare) = 0 Then
If foundColumn > 0 Then
Err.Raise vbObjectError + 1011, , _
"標題「" & expectedHeader & _
"」出現多於一次,請先改成唯一欄名。"
End If
foundColumn = colIndex
End If
End If
Next colIndex
If foundColumn = 0 Then
Err.Raise vbObjectError + 1012, , _
"第一列找不到標題「" & expectedHeader & "」。"
End If
FindUniqueHeaderColumn = foundColumn
End Function
Private Function LastUsedRow(ByVal ws As Worksheet) As Long
Dim lastCell As Range
Set lastCell = ws.Cells.Find( _
What:="*", _
After:=ws.Cells(1, 1), _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False, _
SearchFormat:=False _
)
If lastCell Is Nothing Then
LastUsedRow = 0
Else
LastUsedRow = lastCell.Row
End If
End Function
Private Function LastUsedColumn(ByVal ws As Worksheet) As Long
Dim lastCell As Range
Set lastCell = ws.Cells.Find( _
What:="*", _
After:=ws.Cells(1, 1), _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False, _
SearchFormat:=False _
)
If lastCell Is Nothing Then
LastUsedColumn = 0
Else
LastUsedColumn = lastCell.Column
End If
End Function
Private Function SplitChoices(ByVal value As String) As Variant
value = Replace(value, vbCrLf, ",")
value = Replace(value, vbCr, ",")
value = Replace(value, vbLf, ",")
value = Replace(value, ",", ",")
value = Replace(value, ";", ",")
value = Replace(value, ";", ",")
SplitChoices = Split(value, ",")
End Function
Private Function CleanChoice(ByVal value As String) As String
value = Replace(value, ChrW(160), " ")
value = Replace(value, ChrW(12288), " ")
value = Replace(value, vbTab, " ")
CleanChoice = Trim$(value)
End Function
Private Function SafeOutputValue(ByVal value As Variant) As Variant
Dim firstCharacter As String
If VarType(value) = vbString Then
If Len(value) > 0 Then
firstCharacter = Left$(CStr(value), 1)
Select Case firstCharacter
Case "=", "+", "-", "@"
SafeOutputValue = "'" & CStr(value)
Case Else
SafeOutputValue = value
End Select
Else
SafeOutputValue = value
End If
Else
SafeOutputValue = value
End If
End Function
這段程式實際做了甚麼?
| 程式區段 | 作用 | 安全理由 |
|---|---|---|
Option Explicit 與三個常數 | 強制宣告變數;集中管理來源、輸出和欄名 | 減少拼錯變數或改漏多處名稱 |
ThisWorkbook | 鎖定存放巨集的活頁簿 | 不受使用者當時點選哪個檔案或頁籤影響 |
Find("*") | 從整張表找最後使用列和欄 | 不假設 A 欄永遠完整,也不使用固定資料量 |
FindUniqueHeaderColumn | 找出唯一「報名課程」欄 | 缺欄或同名欄會停止,不會猜其中一欄 |
| 第一遍迴圈 | 檢查錯誤值、計算實際輸出列數 | 在修改輸出前先發現資料問題和列數上限 |
SplitChoices | 把換行、全形逗號和兩種分號統一為逗號再拆分 | 避免只支援單一分隔符 |
SafeOutputValue | 把以 =、+、-、@ 開頭的文字保留為文字 | 降低文字在新儲存格被當成公式的風險 |
GetOrCreateOutputWorksheet | 不存在便建立,存在便重用 | 只清空指定輸出表,不刪來源或其他頁籤 |
CleanExit | 還原 Calculation、Events 和 ScreenUpdating | 錯誤時亦盡量把 Excel 應用程式狀態還原 |
巨集輸出的是值,不是來源公式;這可避免把外部連結或運算邏輯複製到新表。程式亦沿用來源第二列的欄位格式,以便時間戳記和日期正常顯示。若同一欄混合多種格式,應在驗收後統一格式。
步驟六:貼入標準 Module,再編譯
如果你未用過 VBE,可先看 ChatGPT 寫 Excel VBA 入門了解 Module、.xlsm、Alt+F8 和安全警告。這裏只列本案例必需步驟:
- 用 Excel 桌面版開啟測試 .xlsm。
- Windows 可按 Alt+F11;或由 Developer/開發人員 → Visual Basic 開啟 VBE。
- 在左側選中測試檔的
VBAProject,不是 Personal.xlsb 或另一個活頁簿。 - 選 Insert → Module,建立標準 Module。
- 把上方程式由
Option Explicit到最後一個End Function完整貼入。 - 選 Debug → Compile VBAProject;有錯誤便先記下訊息和反白行。
- 儲存、關閉並重開 .xlsm,確認程式仍在。

Excel 網頁版不能執行 VBA。Microsoft 的官方說明指出,網頁版不能建立、執行或編輯 VBA;必須在桌面應用程式操作。
步驟七:先看來源不動,再執行巨集
- 確認目前檔案是 TEST .xlsm,不是原始備份。
- 確認來源頁籤叫「表單回應」,第一列只有一個「報名課程」。
- 記錄來源資料列數,並抽查三個複選儲存格。
- 由 Developer → Macros,或 Windows 按 Alt+F8。
- 選
SplitCheckboxResponses,按 Run/執行。 - 等待完成訊息;資料量大時不要連續重按。
步驟八:逐項驗收「輸出」工作表

完成訊息中的來源列數和輸出列數只是第一層檢查。正式使用前要完成以下驗收:
- 來源不變:來源資料列數、三個抽樣儲存格和工作表修改時間符合預期。
- 總數相等:人工計算小樣本內所有非空白選項總數,應等於輸出資料列數。
- 一格一項:輸出「報名課程」不再含預期分隔符,也沒有前後空白。
- 欄位重複正確:同一來源列拆出的姓名、電郵、電話和時間戳記完全相同。
- 空白不輸出:沒有選項的來源列不應產生一列空白課程。
- 混合符號:逗號、全形逗號、兩種分號和換行的測試列都正確。
- 重跑一致:再執行一次,輸出列數和內容不應倍增。
- 負面測試:把標題暫時改錯或複製一個同名標題,程式應停止並保留舊輸出。

若資料會重複匯出,建議保留穩定的提交 ID;沒有 ID 時可暫用時間戳記加電郵作抽查鍵,但不要假設這個組合永遠唯一。本文故意不自動去重,因為同名、同電郵或同一人多次提交是否應合併,是業務規則,不應由程式自行猜測。
巨集安全:不要為了執行而「啟用所有巨集」
Microsoft 的巨集安全指引明確不建議 Enable all macros。從互聯網或即時通訊下載的 Office 檔案,在 Windows 亦可能按政策被封鎖;應由 IT 或檔案擁有人處理信任和簽署,而不是關掉全域保護。
審查 AI 生成程式時,至少搜尋 Kill、Shell、FileSystemObject、HTTP、Outlook、Workbook_Open、ActiveSheet、Selection。本文範例不需要刪檔、外連、寄信、自動啟動或依賴當前焦點。
私隱:寫 VBA 不需要把真實表格交給 ChatGPT
「只在 Excel 執行」只適用於本文 VBA 本身;如果你把完整回應表貼入或上載 ChatGPT,資料已離開本機工作簿。個人 ChatGPT 工作區的內容是否用於模型改進,取決於帳戶的 Data Controls;可查閱 OpenAI 最新的Data Controls FAQ。OpenAI 的ChatGPT Business 私隱說明指出工作區資料預設不作模型訓練,但公司批准、存取權、保留期和 PDPO 責任仍需獨立處理。
香港私隱公署的僱員使用生成式 AI 指引清單建議機構制定使用範圍、可輸入資料、輸出核實、資料保留、事故回報和培訓安排。實務上應:
- 只提供欄名、資料類型、分隔規則和虛構樣本。
- 以「測試姓名 001」「test001@example.invalid」「9000 0001」取代真實資料。
- 不要把身份證號碼、電話、健康、付款、登入或內部評語放入提示。
- 先確認 Google 表單、連結試算表、下載檔和輸出檔各自的存取權。
- 按用途設定保留期限;完成名單後,不要無限期保留多份本機副本。
- 由資料負責人覆核輸出,而不是把 AI 回覆視為最終決定。
機構若要把這類流程擴展到正式營運,可再按私隱公署的AI 個人資料保障模範框架建立管治、風險評估、人為監督和持續監察安排。
需要更完整的香港情境做法,可參考 ChatGPT 私隱與資料安全指南。
不用 VBA:Power Query、TEXTSPLIT 與 Office Scripts 比較
| 方法 | 最適合 | 優點 | 限制 |
|---|---|---|---|
| VBA | 桌面 Excel、固定流程、一鍵重建輸出 | 可加入驗證、錯誤處理和格式 | 要使用 .xlsm、巨集政策和程式維護 |
| Power Query | 定期匯入、清理、刷新 | 步驟可見,Split into Rows 很直接 | 混合分隔符要先正規化;刷新和權限仍要管理 |
| TEXTSPLIT | 一次性、小量、支援動態陣列的 Excel | 不用巨集,公式即時 | 跨多列堆疊、重複其他欄位和舊版相容較麻煩 |
| Office Scripts | 獲支援的 Microsoft 365 網頁/雲端自動化 | TypeScript、可與雲端流程整合 | 租戶、授權、管理政策及 API 與 VBA 不同 |
Power Query 的等效步驟
- 把來源範圍轉成 Excel Table,保留原始表不改。
- Data → From Table/Range 開啟 Power Query。
- 如有全形逗號、分號或換行,先用 Replace Values 統一為單一分隔符。
- 選「報名課程」→ Split Column → By Delimiter。
- 在 Advanced options 選 Split into Rows,不是 Columns。
- Transform → Format → Trim,再篩走空白。
- Close & Load 到新工作表,刷新後核對列數和抽樣。

可參考 Microsoft 的Power Query 拆欄說明。如果團隊不允許巨集、但需要每週刷新同一份表,Power Query 往往是更容易交接的選擇。
常見錯誤與精確修正
| 現象 | 最可能原因 | 修正方法 |
|---|---|---|
| 找不到來源工作表 | 頁籤不是精確的「表單回應」 | 複製頁籤實際名稱,修改 SOURCE_SHEET 常數;檢查前後空格 |
| 找不到「報名課程」 | 第一列標題不同、合併儲存格或標題列不是第一列 | 把表整理成單一標題列,或修改 CHOICE_HEADER |
| 標題出現多於一次 | 匯出後有兩欄同名 | 先改成唯一欄名,不要讓程式自行猜其中一欄 |
| 一個選項被錯拆成兩個 | 答案內容本身含逗號或分號 | 改表單設計、獨立自由文字欄,或從結構化來源重取 |
| 所有資料仍在一格 | 實際分隔符不在支援清單 | 用純文字工具找出 Unicode 字元,再明確加入 SplitChoices |
| 輸出列數太少 | 空白被略過、資料含錯誤或看似逗號其實是其他符號 | 用小樣本逐格列出預期選項數,再比較完成訊息 |
| 輸出列數第二次倍增 | 執行的不是本文版本,或另一巨集用追加方式 | 確認主程序名稱,搜尋輸出邏輯是否先 Clear |
| 巨集清單沒有程序 | 程式不在標準 Module、編譯錯誤或 Sub 有參數 | 移到標準 Module,Compile,再找無參數 Public Sub |
| 完成後日期變成數字 | 來源第二列格式不是日期或同欄混合格式 | 在輸出表統一套用日期格式;值本身未必錯 |
| 安全警告阻止執行 | 下載來源標記、企業政策或未信任檔案 | 不要全域啟用;核對來源並交 IT 按政策處理 |
向 ChatGPT 回報錯誤時,只提供錯誤編號、完整訊息、VBE 反白行、虛構欄位結構、預期結果和實際結果。不要因為除錯而上載整份正式名單。
交付正式名單前的最後檢查
- 原始 Google 回應、RAW 下載檔和 TEST .xlsm 分開保存,沒有覆蓋唯一來源。
- 來源與輸出工作表名稱固定,欄名有版本控制。
- 測試包含半形/全形逗號、兩種分號、換行、空白、錯誤值和答案內分隔符。
- 總選項數等於輸出資料列數,並完成至少 10 個來源列的逐項抽查。
- 第二次執行結果一致,沒有在舊輸出底部追加。
- 沒有未批准的刪檔、外連、寄信、Shell、自動開啟或 ActiveSheet 行為。
- 輸出接收者、分享方式和保留期限已批准;不再需要的測試副本已按政策處理。
- 若新回應仍持續進入 Google Sheet,已清楚標示本次匯出的截止時間。
下一步:由一次拆分升級成可維護流程
這個案例的真正價值不只是「ChatGPT 幫你寫 VBA」,而是把模糊需求變成可測試規格:固定來源、固定輸出、清楚分隔規則、錯誤時停止、重跑不累積、完成後可驗算。相同方法可延伸到活動時段、技能標籤、服務地區或多選問卷,但每次都要先確認分隔符和業務去重規則。
若你想理解 ChatGPT 在 Excel 的公式、分析、圖表和報告用途,可閱讀 ChatGPT Excel 香港工作指南;要把多個重複辦公步驟串成流程,可再看 香港中小企 AI 自動化指南和 香港工作提示詞實例。
資料來源與引用
我們附上第一手及官方來源,方便你逐一核實。
- 1.Choose a type of question for your form — Google Docs Editors Help
- 2.View & manage form responses — Google Docs Editors Help
- 3.Choose where to save form responses — Google Docs Editors Help
- 4.Show the Developer tab — Microsoft Support
- 5.Run a macro in Excel — Microsoft Support
- 6.Save a macro — Microsoft Support
- 7.File formats that are supported in Excel — Microsoft Support
- 8.Change macro security settings in Excel — Microsoft Support
- 9.Macros from the internet are blocked by default in Office — Microsoft Learn
- 10.Work with VBA macros in Excel for the web — Microsoft Support
- 11.Split a column of text (Power Query) — Microsoft Support
- 12.Split a cell in Excel — Microsoft Support
- 13.Introduction to Office Scripts in Excel — Microsoft Support
- 14.Data Controls FAQ — OpenAI Help Center
- 15.Managing data, sharing, and privacy in ChatGPT Business — OpenAI Help Center
- 16.Checklist on Guidelines for the Use of Generative AI by Employees — Office of the Privacy Commissioner for Personal Data, Hong Kong
- 17.Artificial Intelligence: Model Personal Data Protection Framework — Office of the Privacy Commissioner for Personal Data, Hong Kong
常見問題
Google 表單的核取方塊答案為甚麼會擠在同一格?
核取方塊允許同一位填表者選多個答案,但試算表仍以一次提交為一列,所以多個選項會序列化在同一儲存格。這適合保留原始回應,卻不方便按選項篩選、樞紐分析或匯入其他系統。
這個 VBA 會修改 Google 表單或來源工作表嗎?
不會。程式只讀取 ThisWorkbook 內名為「表單回應」的工作表,並把結果寫到「輸出」。它不連接 Google、不回寫表單,也不改來源儲存格;不過仍應先在副本測試。
複選欄不是「報名課程」怎麼辦?
只修改程式開首的 CHOICE_HEADER 常數,令它與第一列標題完全相同。若工作表名也不同,修改 SOURCE_SHEET;不要把 ActiveSheet 當捷徑。
選項含逗號或「其他」自由文字,仍可安全拆分嗎?
不一定。若逗號既是分隔符又可能是答案內容,純文字已失去結構資訊,任何逗號拆分都可能誤切。應限制選項文字、另設自由文字欄、改用不會出現在答案內的分隔符,或從結構化來源重新取得資料。
為甚麼第二次執行不會一直新增重複列?
巨集每次都先在記憶體重建完整結果,驗證成功後才清空指定的「輸出」工作表再一次寫入。它不會在舊輸出底部追加;來源本身若有重複答案,則會忠實保留供追查。
Excel 網頁版可不可以執行這段 VBA?
不可以。Microsoft 說明 Excel for the web 不能建立、執行或編輯 VBA。請用桌面 Excel;若流程必須在網頁或雲端執行,可評估 Office Scripts 或 Power Automate。
一定要把真實 Excel 檔案上載給 ChatGPT 嗎?
不需要,也不建議。為這類程式提供工作表名、欄位名、分隔規則、兩三列虛構輸入與預期輸出已足夠。真實姓名、電郵、電話和報名內容應留在獲批准的系統內。
不用 VBA 還有甚麼方法?
需要可刷新清理流程時,Power Query 的 Split Column by Delimiter 並選 Split into Rows 通常更易審計;一次性小資料可用 TEXTSPLIT;雲端 Microsoft 365 流程可評估 Office Scripts。
本文遵循我們的 編輯準則.

關於作者
HK Learn AI 編輯部
HK Learn AI 編輯部負責研究、查證同編寫每一篇內容,並引用官方及第一手來源。
此主題相關文章

ChatGPT 協作 Excel:寫公式、生成 VBA、自動製圖與匯出 PDF 報表
用一份虛構銷售明細完整示範:先讓 ChatGPT 理解欄位與驗收規格,再建立列級銷售額、業務彙總與佔比公式,審查 VBA、重建直條圖,資料適合時再建立圓餅圖,最後輸出具時間戳的 PDF。

ChatGPT 寫 Excel VBA 入門:貼上、儲存與執行 AI 巨集完整教學
拿到 ChatGPT 產生的 VBA 卻不知道放哪裏?由開啟 VBE、插入標準 Module、檢查程式、另存 .xlsm 到執行巨集與安全除錯,逐步把 AI 程式碼變成可測試、可回復的 Excel 自動化。

AI 寵物 Podcast 完整教學:用小雲雀、即夢製作貓狗吐槽對話影片
由一張貓狗 Podcast 畫面開始,逐步示範拆解參考、寫雙角色對白、用小雲雀快速生成,以及在即夢建立寵物主持圖、製作逐句對口型和剪成多人對話。本文按 2026 年 7 月現行介面修正舊版模型名稱,附可直接改寫的提示詞、成品預覽、費用判斷與逐格品質檢查。