【VBA】数式を値に一括変換して計算負荷を減らす方法(コピペOK)

VBA
スポンサーリンク

記事ID: 133
タイトル: 数式を値に一括変換して計算負荷を減らす方法
カテゴリ: シート操作
一次キーワード: VBA 数式 値 貼り付け 一括変換
想定読者: 数式が大量にあるシートの動作が重く、確定済みのデータを値に変換したい実務担当者
検索意図: VBAで数式を値に一括変換して計算の重さを解消したい
読者の悩み(1文): 数式が大量にあるシートが重く、確定データの数式を値に変換したいが1範囲ずつ手作業で貼り直すのが面倒。
読了後にできること(1文): VBAで数式を値に一括変換し、確定済みデータの計算負荷を削減できるようになる。
前提条件:
  - Excel版: Excel 2016以降 / Microsoft 365
  - OS: Windows 10/11
  - 保存形式: .xlsm(マクロ有効ブック)
  - 貼り付け場所: 標準モジュール
  - 実行方法: Alt+F8 → マクロ実行 / ボタン割り当て
更新日: 2026-03-24

スポンサーリンク

この記事でわかること

  • VBAで数式を値に一括変換できる
  • Range.Value = Range.ValuePasteSpecial xlValues の使い分けがわかる
  • 数式セルだけを自動検出し、確認ダイアログ+バックアップ付きで安全に変換できる

対象: Excel 2016以降 / Microsoft 365、Windows 10/11

どんな場面で使う?

  • 数式だらけのシートが重いので確定済みデータを値に変換して軽くしたいとき
  • 月末の締め作業で過去月シートの数式を一括で値化したいとき
  • 数式セルだけを自動検出してピンポイントで値変換したいとき
  • 変換前に自動バックアップを取って安全に作業したいとき

完成イメージ(Before / After)

Before(手作業): 範囲を選択 → コピー → 「値として貼り付け」。範囲が複数あると何度も繰り返し。

After(VBA実行後): ボタン1つで指定範囲の数式をすべて値に変換。バックアップシートも自動作成されるので安心。

自分も以前、月次集計のシートに数式が数千個あって、ファイルを開くだけで30秒以上かかっていた。確定済みの過去月データなのに毎回再計算が走る。手動で「値として貼り付け」しようにも、範囲が飛び飛びで10回以上繰り返す必要があった。地味にストレスだった。VBAで一括変換するようにしてからは、月末の締め作業が1クリックで終わるようになった。この記事で、同じように数式の重さに困っている人がサクッと解消できればうれしい。

VBAの Range.Value = Range.Value を使えば、数式を値に一括変換できる。

なお、配列を使った高速処理の基本は 配列を使ってVBAの処理速度を10倍にする方法 を参照。ScreenUpdatingCalculation を止めて高速化する方法は 画面更新・再計算を止めてマクロを高速化する方法 を参照。

実行前の準備

バックアップを取る

数式を値に変換すると元の数式は消えます。元に戻せません(Ctrl+Z も複数操作後は効かない)。 必ずファイルのコピーを別フォルダに保存してから実行してください。実務版コードではバックアップシートを自動作成しますが、ファイル単位のバックアップも推奨します。

Excelをマクロ有効ブック(.xlsm)で保存する

拡張子が .xlsx のままだとマクロが保存できない。

  1. 「ファイル」→「名前を付けて保存」
  2. ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
  3. 保存

手順(コピペ → 実行まで約5分)

VBE(コードを書く画面)を開く

  1. Excelで Alt + F11 を押す

標準モジュールを挿入する

  1. VBEのメニュー →「挿入」→「標準モジュール」

コードを貼り付けて実行する

  1. コードウィンドウに、下のコードをそのままコピペする
  2. Alt + F8 → マクロ名を選んで「実行」

ボタンに割り当てれば毎回Alt+F8を押さなくて済む。方法は マクロをボタン1つで実行する方法 を参照。

コード(最小版)– 指定範囲の数式を値に変換する

A1:F100の数式をすべて値に変換する。まずはこれで動きを確認する。


'============================================================
' ■ 数式を値に一括変換する(最小版)
'   → A1:F100の数式をすべて値に変換
'============================================================
Sub ConvertFormulasToValues()

    Dim ws As Worksheet
    Set ws = ActiveSheet

    '--- 数式を値に一括変換(この1行だけで完了)
    ws.Range("A1:F100").Value = ws.Range("A1:F100").Value

    MsgBox "A1:F100の数式を値に変換しました。", vbInformation

End Sub

ポイント

  • Range.Value = Range.Value は、右辺で数式の計算結果(値)を取得し、左辺でその値を上書きする。結果として数式が値に置き換わる
  • コードはたった1行。シンプルだが不可逆操作なので注意
  • 数式がないセル(文字列や数値のみ)は値がそのまま再代入されるだけで影響なし

Range.Value = Range.Value と PasteSpecial xlValues の比較

数式を値に変換する方法は2つある。

項目 Range.Value = Range.Value PasteSpecial xlValues
コード量 1行 3〜4行(Copy → PasteSpecial → CutCopyMode)
速度 速い(クリップボード不使用) やや遅い(クリップボード経由)
クリップボード 汚さない 使用する(他のコピー内容が消える)
書式への影響 なし(値だけ置換) なし(xlValues指定なら値だけ)
結合セル そのまま処理可能 エラーになる場合がある
おすすめ場面 ほぼすべての場面 他のアプリとの互換性が必要な場合

結論: 基本は Range.Value = Range.Value を使えばOK。 PasteSpecialは互換性が必要な特殊ケースのみ。

参考として PasteSpecial を使う場合のコード:


Sub ConvertFormulasToValuesPasteSpecial()

    Dim rng As Range
    Set rng = ActiveSheet.Range("A1:F100")

    rng.Copy
    rng.PasteSpecial Paste:=xlPasteValues
    Application.CutCopyMode = False    '← クリップボードをクリア

    MsgBox "値に変換しました。", vbInformation

End Sub

クリップボードの操作については クリップボードを使ってデータをコピー・貼り付け・クリアする方法 を参照。

コード(実務版)– 数式セルのみ検出+確認ダイアログ+バックアップシート作成

自分はこの方法を覚えてからは、月次締め作業で「うっかり数式を消してしまった」という事故がなくなった。バックアップシートがあるので安心して実行できる。


'============================================================
' ■ 数式を値に一括変換する(実務版)
'   → 数式セルのみ検出+確認ダイアログ+バックアップシート作成
'============================================================
Sub ConvertFormulasToValuesAdvanced()

    Dim ws As Worksheet
    Dim formulaCells As Range
    Dim backupWs As Worksheet
    Dim formulaCount As Long
    Dim answer As VbMsgBoxResult

    Set ws = ActiveSheet

    '--- 数式セルを検出 -----【ここが追加】
    On Error Resume Next
    Set formulaCells = ws.Cells.SpecialCells(xlCellTypeFormulas)
    On Error GoTo 0

    '--- 数式がなければ終了
    If formulaCells Is Nothing Then
        MsgBox "このシートに数式セルはありません。", vbInformation
        Exit Sub
    End If

    '--- 数式セルの個数を取得
    formulaCount = formulaCells.Count

    '--- 確認ダイアログ -----【ここが追加】
    answer = MsgBox("シート「" & ws.Name & "」に数式セルが " & formulaCount & " 個あります。" & vbCrLf & _
                    vbCrLf & _
                    "すべて値に変換しますか?" & vbCrLf & _
                    "(変換前にバックアップシートを作成します)", _
                    vbYesNo + vbQuestion, "数式→値 一括変換")

    If answer <> vbYes Then
        MsgBox "処理をキャンセルしました。", vbInformation
        Exit Sub
    End If

    '--- バックアップシートを作成 -----【ここが追加】
    ws.Copy After:=ws
    Set backupWs = ActiveSheet
    backupWs.Name = ws.Name & "_BK_" & Format(Now, "yyyyMMdd_HHmmss")

    '--- 元のシートに戻る
    ws.Activate

    '--- 高速化設定
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

    '--- 数式セルだけ値に変換 -----【ここが追加】
    Dim area As Range
    For Each area In formulaCells.Areas
        area.Value = area.Value
    Next area

    '--- 高速化設定を戻す
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True

    MsgBox formulaCount & " 個の数式を値に変換しました。" & vbCrLf & _
           "バックアップシート: 「" & backupWs.Name & "」", vbInformation

End Sub

実務版のポイント

  • SpecialCells(xlCellTypeFormulas) で数式セルだけを自動検出。値のみのセルには触れない
  • 確認ダイアログで個数を表示し、意図しない実行を防止
  • バックアップシートを自動作成。「やっぱり数式に戻したい」ときはバックアップからコピーできる
  • Areas プロパティで不連続範囲を1つずつ処理。SpecialCells の結果は不連続になるため、まとめて代入するとエラーになるケースがある
  • ScreenUpdatingCalculation を止めて高速化

落とし穴

# 症状 原因 対策
1 数式を元に戻せない Range.Value = Range.Value は不可逆操作。Ctrl+Zも効かない場合がある 実務版のようにバックアップシートを作成してから実行する。自分も最初これに気づかず、過去月の集計式を全部消してしまい3時間かけて復元した
2 SpecialCells でエラーが出る 数式セルが1つもないときに SpecialCells(xlCellTypeFormulas) を呼ぶとエラーになる On Error Resume Next で囲み、Nothing チェックする。実務版コードではこの対策済み
3 大量の数式セルで処理が遅い 数万セルの数式を一括変換すると時間がかかる ScreenUpdating = FalseCalculation = xlCalculationManual で高速化。実務版では設定済み
4 他のセルが参照エラー(#REF!)になる 値に変換したセルを参照している別シートの数式が、参照元の変更で壊れることがある 変換前に「このセルを参照しているセルがないか」確認する。Ctrl + ](参照先トレース)で事前チェック
5 バックアップシート名が31文字を超えてエラーになる Excelのシート名は31文字制限。元のシート名が長いとタイムスタンプ付加で超過する バックアップシート名を短くする。例: Left(ws.Name, 15) & "_BK_" & Format(Now, "yyyyMMdd")
6 配列数式(CSE数式やSPILL数式)が正しく変換されない 配列数式は Range.Value = Range.Value で一部のセルだけ変換するとエラーになることがある 配列数式の範囲全体をまとめて変換する。SPILL数式の場合はスピル範囲全体を対象にする
7 結合セルでエラーが出る SpecialCells が結合セル全体を返さず一部だけ返す場合がある 結合セルがある場合は結合を解除してから値変換するか、PasteSpecial を使う

VBAで数式を値に変換したら元に戻せなくなったときの対処法

「値に変換した後でやっぱり数式が必要になった」という場合、VBAでの値変換はCtrl+Zで元に戻せない。対策は変換前にバックアップシートを自動作成すること。実務版コードにはバックアップ機能が含まれているので、変換前の状態にいつでも戻せる。

VBAの値変換で一部のセルだけ変換されないときの対処法

「実行したのに数式が残っているセルがある」という場合、原因は結合セルや保護セルが含まれていること。結合セルは事前に解除するか、結合セルをスキップする処理を入れる。保護シートの場合はUnprotectしてから変換する。

FAQ

Q1. 特定のシートだけ値に変換したい場合は?

シート名を指定して処理する。


Sub ConvertSpecificSheet()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("集計")

    Dim formulaCells As Range
    On Error Resume Next
    Set formulaCells = ws.Cells.SpecialCells(xlCellTypeFormulas)
    On Error GoTo 0

    If Not formulaCells Is Nothing Then
        Dim area As Range
        For Each area In formulaCells.Areas
            area.Value = area.Value
        Next area
    End If
End Sub

セルの転記と組み合わせる場合は セルの転記を自動化する方法 を参照。

Q2. VLOOKUP や SUMIFS などの特定の関数だけ値に変換できる?

SpecialCells では関数の種類までは絞れない。セルごとに Formula プロパティを検査して判定する。


Dim c As Range
For Each c In ws.UsedRange
    If c.HasFormula Then
        If InStr(1, c.Formula, "VLOOKUP", vbTextCompare) > 0 Then
            c.Value = c.Value
        End If
    End If
Next c

ただし大量のセルに対してセル単位ループは遅い。配列で処理する方法は 配列を使ってVBAの処理速度を10倍にする方法 を参照。

Q3. 複数シートの数式を一括で値に変換できる?

For Each ws In ThisWorkbook.Worksheets でループすればOK。


Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
    Dim formulaCells As Range
    Set formulaCells = Nothing
    On Error Resume Next
    Set formulaCells = ws.Cells.SpecialCells(xlCellTypeFormulas)
    On Error GoTo 0
    If Not formulaCells Is Nothing Then
        Dim area As Range
        For Each area In formulaCells.Areas
            area.Value = area.Value
        Next area
    End If
Next ws

Q4. 変換後にファイルサイズが変わらないのはなぜ?

数式を値に変換してもファイルサイズが劇的に減るわけではない。計算負荷(開くときの再計算時間)が減るのが主な効果。ファイルサイズを減らしたい場合は、不要な書式や空白セルの削除を検討する。

Q5. マクロの実行を元に戻す方法は?

Range.Value = Range.Value の実行後は Ctrl+Z で戻せない場合がある(VBA操作は標準のUndo履歴に入らないため)。実務版で作成されるバックアップシートから数式をコピーして復元するのが確実。

まとめ

この記事では、VBAで数式を値に一括変換する方法を紹介した。

  • 基本: Range.Value = Range.Value の1行で変換完了
  • 実務では: SpecialCells で数式セルだけ検出し、確認ダイアログ+バックアップシート付きで安全に変換
  • PasteSpecial との比較: 基本は Range.Value 方式が速くてシンプル。クリップボードも汚さない
  • 注意点: 不可逆操作なので必ずバックアップを取ってから実行する

次にやりたくなること

コメント

タイトルとURLをコピーしました