読者です 読者をやめる 読者になる 読者になる

kurukuru-papaのブログ

主に、ソフトウェア開発に関連したメモを書き溜めたいと思います。

Excelファイルのシートのページ数を取得する方法

Excelファイルの各シートについて、ページ数を取得する方法は、2つあるようです。

ただし、どちらの方法でも、縦と横の両方が複数ページにわたるようなワークシートでは、場合によっては、誤ったページ数を返却します。詳細は機械猫さんの次のサイトを見てください。

方法1

Excel 4 マクロを使用してワークシートを印刷する際の総ページ数を調べる方法です。

次のようになります。ここで、sheet.Nameは、ページ数を取得したいワークシートの名前です。この引数を指定しない場合は、アクティブなワークシートのページ数が返却されます。

page = xl.ExecuteExcel4Macro("Get.Document(50,\"#{sheet.Name}\")").to_i

なお、Microsoftのサイトからの情報では、次のような注意がありました。

  • 指定したファイルがグラフのときは 1 が返されます。
  • 印刷範囲を指定し、[ファイル] メニューの [ページ設定] にて "横 1 ×縦 1 ページに印刷" と設定していると、正しい結果が取得できないことがあります。その場合、以下のいずれかの方法で回避できます。
    • [ファイル] メニューの [ページ設定] から "拡大/縮小" で倍率を指定する。
    • [ファイル] メニューの [ページ設定] から [印刷範囲] を設定しない。

サンプルプログラムです。

#! ruby -Ks
require 'win32ole'

xl = nil
book = nil
path = ARGV[0]

begin
	# 絶対パスを取得します。
	fso = WIN32OLE.new('Scripting.FileSystemObject')
	absolute_path = fso.GetAbsolutePathName(path)

	# Excelアプリを起動します。
	xl = WIN32OLE.new('Excel.Application')

	# ファイルを開きます。
	book = xl.Workbooks.Open(absolute_path)

	# シート数分ループします。
	book.Worksheets.each { |sheet|
		# ページ数を取得します。
		# Get.Documentでは、第2引数にシート名を渡すと、該当シートのページ数が返却されます。
		# 第2引数を指定しないと、アクティブなシートのページ数が返却されます。
		page = xl.ExecuteExcel4Macro("Get.Document(50,\"#{sheet.Name}\")").to_i
		# 出力します。
		puts "#{path},#{sheet.Name},#{page}"
	}
rescue
	puts "#{path} の読み込みに失敗しました。"
ensure
	# ファイルをクローズします。
	book.Close if book
	# Excelアプリを終了します。
	xl.Quit if xl
end

参考

方法2

この方法では、Excel 4 のマクロは使用しません。

次のget_page関数のようになります。引数にSheetオブジェクトを渡すと、そのワークシートのページ数を返却してくれます。

# シートのページ数を取得します。
def get_page(sheet)
	# 最後のセルのアドレスを取得します。
	cell = sheet.UsedRange.Address
	puts "cell=#{cell}" if $DEBUG
	
	if cell == "$A$1" then
		# 印刷できるデータが存在しない場合
		page = 0
	else
		# 横の改ページ数取得
		hcount = sheet.HPageBreaks.Count
		puts "hcount=#{hcount}" if $DEBUG
		# 縦の改ページ数取得
		vcount = sheet.VPageBreaks.Count
		puts "vcount=#{vcount}" if $DEBUG
		if vcount == 0 then
			page = hcount + 1
		else
			hcount += 1
			vcount += 1
			page = hcount * vcount
		end
	end
	return page
end

なお、Microsoftのサイトからの情報では、次のような注意がありました。

  • 実行する前に、改ページ位置のセルを画面に表示して、改ページ位置を認識させる必要があります。次のいずれかの操作を 1 度実行します。
    • 改ページされているセルを画面に表示
    • ZOOM で縮小したあと元に戻す
    • 印刷プレビューを実行する
  • 既に改ページが挿入されている状態で最後のページのデータを削除すると、正しいページ数が取得できません。データの加工によりページ数が減少する場合には、手動で改ページを設定し直す必要があります。

サンプルプログラムです。

#! ruby -Ks
require 'win32ole'

# シートのページ数を取得します。
def get_page(sheet)
	# 最後のセルのアドレスを取得します。
	cell = sheet.UsedRange.Address
	puts "cell=#{cell}" if $DEBUG
	
	if cell == "$A$1" then
		# 印刷できるデータが存在しない場合
		page = 0
	else
		# 横の改ページ数取得
		hcount = sheet.HPageBreaks.Count
		puts "hcount=#{hcount}" if $DEBUG
		# 縦の改ページ数取得
		vcount = sheet.VPageBreaks.Count
		puts "vcount=#{vcount}" if $DEBUG
		if vcount == 0 then
			page = hcount + 1
		else
			hcount += 1
			vcount += 1
			page = hcount * vcount
		end
	end
	return page
end

xl = nil
book = nil
path = ARGV[0]

begin
	# 絶対パスを取得します。
	fso = WIN32OLE.new('Scripting.FileSystemObject')
	absolute_path = fso.GetAbsolutePathName(path)

	# Excelアプリを起動します。
	xl = WIN32OLE.new('Excel.Application')

	# ファイルを開きます。
	book = xl.Workbooks.Open(absolute_path)

	# シート数分ループします。
	book.Worksheets.each { |sheet|
		# ページ数を取得します。
		page = get_page(sheet)
		# 出力します。
		puts "#{path},#{sheet.Name},#{page}"
	}
rescue
	puts "#{path} の読み込みに失敗しました。"
ensure
	# ファイルをクローズします。
	book.Close if book
	# Excelアプリを終了します。
	xl.Quit if xl
end

参考

私の動作環境