C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: Excelの印刷範囲指定と改ページ


(過去ログ 122 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■73221 / inTopicNo.1)  Excelの印刷範囲指定と改ページ
  
□投稿者/ さとすけ (8回)-(2014/08/29(Fri) 13:52:18)

分類:[C#] 

2014/08/29(Fri) 13:53:55 編集(投稿者)
お世話になっております。

Excelの印刷範囲についてつまってしまいました。
もしご存知の方がいらっしゃいましたらご教授お願いいたします。

次のようなデータのExcelが対象です。
(セルA1に1, セルB1に2・・・)


1 2 3 4 5 6 7 8 9 0
a b c d e f g h i j
k l m n o p q r s t
u v w x y z A B C D
E F G H I J K L M N


それを次のように3ページで印刷したいと考えています。


1 2 3 4 5 6 7 8 9 0
a b c d e f g h i j
-------------------
k l m n o p q r s t
-------------------
u v w x y z A B C D
E F G H I J K L M N


しかし、当方の実装では次のように印刷範囲が区切られてしまいます。


1 2 3 4 5 | 6 7 8 9 0
a b c d e | f g h i j
----------+----------
k l m n o | p q r s t
----------+----------
u v w x y | z A B C D
E F G H I | J K L M N


5列と6列の間の縦の区切りを消したい、
もしくは最後の右列まで伸ばしたい、
と考えていますがその方法がわかりませんでした。
(なお、縦線は青い点線、横線は青い実線でした)

ソースは以下のものです。
よろしくお願いいたします。

@ソース
-----------------------------------
Excel.Application ExcelApp = new Excel.Application();
Excel.Workbooks books = ExcelApp.Workbooks;
Excel.Workbook Book = books.Add();
Excel.Sheets sheets = Book.Sheets;
Excel.Worksheet sheet = (Excel.Worksheet)sheets[1];

// データ設定
for (int x = 1; x <= 20; x++)
{
	for (int y = 1; y <= 100; y++)
	{
		SetData(sheet, x, y, (x + y).ToString());
	}
}

// 印刷方向を横向き
// →縦線は多少右にずれたが、消えるにはいたらなかった
Excel.PageSetup page = sheet.PageSetup;
page.Orientation = Excel.XlPageOrientation.xlLandscape;
Marshal.ReleaseComObject(page);

// 改ページ解除
// →自動で挿入される改ページには効果がないのか、縦線は消せなかった
sheet.ResetAllPageBreaks();

// 任意の行で改ページ
SetKaiPage(sheet, 1, 6, 1, 6);

// 任意の行で改ページ
SetKaiPage(sheet, 1, 8, 1, 8);

Book.SaveAs(@"d:\tmp\a.xlsx");
Book.Close(false, Missing.Value, Missing.Value);

ExcelApp.Quit();

Marshal.ReleaseComObject(sheet);
if (Marshal.IsComObject(sheets)) Marshal.ReleaseComObject(sheets);
Marshal.ReleaseComObject(Book);
if (Marshal.IsComObject(books)) Marshal.ReleaseComObject(books);
Marshal.ReleaseComObject(ExcelApp);
-----------------------------------

@関数群
-----------------------------------
private void SetData(Excel.Worksheet sheet, int x, int y, String data)
{
	Excel.Range range0 = sheet.Cells;
	Excel.Range range1 = range0.Item[y, x];

	range1.Value2 = data;

	Marshal.ReleaseComObject(range1);
	Marshal.ReleaseComObject(range0);
}
		
private void SetKaiPage(Excel.Worksheet sheet, int startX, int startY, int endX, int endY)
{
	Excel.Range range0 = sheet.Cells;
	Excel.Range range1 = range0.Item[startY, startX];
	Excel.Range range2 = range0.Item[endY, endX];
	Excel.Range range3 = sheet.Range[range1, range2];

	range3.PageBreak = (int)Excel.XlPageBreak.xlPageBreakManual;

	Marshal.ReleaseComObject(range0);
	Marshal.ReleaseComObject(range1);
	Marshal.ReleaseComObject(range2);
	Marshal.ReleaseComObject(range3);
}
-----------------------------------

@環境
-----------------------------------
IDE :
 Visual Studio Professinal 2012 (11.0.60610.01 Update3)

Framework :
 .NET Framework 4.5.50709

参照設定に追加 : 
 Microsoft.Office.Interop.Excel (14.0.0.0)
 Microsoft.Iffice.Core(Microsoft Office 15.0 Object Library)

Office : 
 Office Home and Business 2010
-----------------------------------

引用返信 編集キー/
■73223 / inTopicNo.2)  Re[1]: Excelの印刷範囲指定と改ページ
□投稿者/ shu (615回)-(2014/08/29(Fri) 15:14:10)
No73221 (さとすけ さん) に返信

まず5列まででページ幅がいっぱいになっているとか6列まではページ幅に収まらないいうことはないのでしょうか?


引用返信 編集キー/
■73225 / inTopicNo.3)  Re[2]: Excelの印刷範囲指定と改ページ
□投稿者/ さとすけ (9回)-(2014/08/29(Fri) 15:40:01)
ご返事ありがとうございます。

> まず5列まででページ幅がいっぱいになっているとか6列まではページ幅に収まらないいうことはないのでしょうか?

はい、ご指摘の通り、5列まででページ幅がいっぱいになっています。
6列からは5列までのページに収まっていない状態です。


1 2 3 4 5 | 6 7 8 9 0
a b c d e | f g h i j
----------+----------
k l m n o | p q r s t
----------+----------
u v w x y | z A B C D
E F G H I | J K L M N


1〜5、a〜e までが1ページ
6〜0、f〜j までが2ページ
といった状態です。

引用返信 編集キー/
■73227 / inTopicNo.4)  Re[3]: Excelの印刷範囲指定と改ページ
□投稿者/ shu (617回)-(2014/08/29(Fri) 15:49:31)
No73225 (さとすけ さん) に返信
> ご返事ありがとうございます。
>
>>まず5列まででページ幅がいっぱいになっているとか6列まではページ幅に収まらないいうことはないのでしょうか?
>
> はい、ご指摘の通り、5列まででページ幅がいっぱいになっています。
> 6列からは5列までのページに収まっていない状態です。
>
印刷時に100%の大きさで印刷したらこれはどうにもならないです。
なので拡大率をしてするなどでして横がページ内に収まるようにする必要があります。
WorkSheet.PageSetup.Zoom
WorkSheet.PageSetup.FitToPagesWide = 1
などで調整するとどうでしょう?
引用返信 編集キー/
■73228 / inTopicNo.5)  Re[1]: Excelの印刷範囲指定と改ページ
□投稿者/ 魔界の仮面弁士 (111回)-(2014/08/29(Fri) 15:56:11)
No73221 (さとすけ さん) に返信
> // データ設定

セル一つずつに個別に渡すのでは無く、A1:T100 の Range に 2 次元配列を渡して、
まとめてセットした方が良いですよ。


> それを次のように3ページで印刷したいと考えています。

「用紙向きは横」で、「縦3ページ」「横1ページ」に収まるように縮小したいなら、こんな感じ。
最大3ページというだけなので、データ数が少ない場合は1〜2ページで出力されることもあります。


float ver = float.Parse(Regex.Match(ExcelApp.Version, @"(\d+(\.\d+)?)").Value);
if (ver < 13) {
  // PageSetup オブジェクトの動作は遅いので、PAGE.SETUP マクロで一括指定する
  ExcelApp.ExecuteExcel4Macro(@"PAGE.SETUP(,,,,,,,,,,2,,{1,3})");
} else {
  // Excel 2010 以降では PrintCommunication プロパティが追加されている
  ExcelApp.PrintCommunication = false;
  Excel.PageSetup page = sheet.PageSetup;
  page.Orientation = Excel.XlPageOrientation.xlLandscape;
  page.FitToPagesTall = 3;
  page.FitToPagesWide = 1;
  ExcelApp.PrintCommunication = true;
  Marshal.ReleaseComObject(page);
}


> range3.PageBreak = (int)Excel.XlPageBreak.xlPageBreakManual;

改ページを挿入する場合は、上記のほか、HPageBreaks.Add を用いる方法もあります。
ただし、参照カウントが増加する場合があるという…。
http://hpcgi1.nifty.com/MADIA/VBBBS2/wwwlng.cgi?print+200512/05120042.txt
引用返信 編集キー/
■73229 / inTopicNo.6)  Re[4]: Excelの印刷範囲指定と改ページ
□投稿者/ さとすけ (10回)-(2014/08/29(Fri) 16:11:08)
ご回答ありがとうございます。

> WorkSheet.PageSetup.Zoom
> WorkSheet.PageSetup.FitToPagesWide = 1
> などで調整するとどうでしょう?

教えて頂きました内容を実装したところ、
望む結果を得ることができました。

本当にありがとうございました。

修正版のソースは以下のようになりました。

------------------------------------
Excel.Application ExcelApp = new Excel.Application();
Excel.Workbooks books = ExcelApp.Workbooks;
Excel.Workbook Book = books.Add();
Excel.Sheets sheets = Book.Sheets;
Excel.Worksheet sheet = (Excel.Worksheet)sheets[1];

// データ設定
for (int x = 1; x <= 20; x++)
{
	for (int y = 1; y <= 100; y++)
	{
		SetData(sheet, x, y, (x + y).ToString());
	}
}

// 横幅は1ページで収まるように拡大/縮小、縦は任意ページで印刷
Excel.PageSetup page2 = sheet.PageSetup;
page2.Zoom = false;
page2.FitToPagesTall = false;
page2.FitToPagesWide = 1;
Marshal.ReleaseComObject(page2);

// 任意の行で改ページ
SetKaiPage(sheet, 1, 6, 1, 6);

// 任意の行で改ページ
SetKaiPage(sheet, 1, 8, 1, 8);

Book.SaveAs(@"d:\tmp\a.xlsx");
Book.Close(false, Missing.Value, Missing.Value);

ExcelApp.Quit();

Marshal.ReleaseComObject(sheet);
if (Marshal.IsComObject(sheets)) Marshal.ReleaseComObject(sheets);
Marshal.ReleaseComObject(Book);
if (Marshal.IsComObject(books)) Marshal.ReleaseComObject(books);
Marshal.ReleaseComObject(ExcelApp);
-------------------------------------
# 関数群は同じであるため省略

解決済み
引用返信 編集キー/
■73232 / inTopicNo.7)  Re[5]: Excelの印刷範囲指定と改ページ
□投稿者/ さとすけ (11回)-(2014/08/29(Fri) 17:07:02)
魔界の仮面弁士様

いつもありがとうございます。

> セル一つずつに個別に渡すのでは無く、A1:T100 の Range に 2 次元配列を渡して、
> まとめてセットした方が良いですよ。

自分のサンプルがどうも遅いと感じていましたが、
上記の点修正したところだいぶ早くなりました。

処理時間:10秒→2秒

> PAGE.SETUP マクロ
> PrintCommunication

どちらもPageSetup高速化対応とのことで、貴重な情報をありがとうございます。

実装マシンではExcel2010を使用しますため、
PrintCommunicationの制御を実装させて頂く予定ですが、
2010未満の環境で実装する場合はPAGE.SETUP マクロも使用させて頂きます。

> 改ページを挿入する場合は、上記のほか、HPageBreaks.Add を用いる方法もあります

こちらも確認してみます。

ご指摘ありがとうございました。
修正しましたソースは以下のようになりました。
----------------------------
Excel.Application ExcelApp = new Excel.Application();
Excel.Workbooks books = ExcelApp.Workbooks;
Excel.Workbook Book = books.Add();
Excel.Sheets sheets = Book.Sheets;
Excel.Worksheet sheet = (Excel.Worksheet)sheets[1];

// データ設定
object[,] data = new object[100, 20];
for (int x = 1; x <= 20; x++)
{
	for (int y = 1; y <= 100; y++)
	{
		data[y - 1, x - 1] = x + y;
	}
}
SetData(sheet, 1, 1, 20, 100, data);

// 印刷設定
// - 横向き
// - 横幅は1ページに収まるように縮小/拡大、縦は任意ページ
ExcelApp.PrintCommunication = false;
Excel.PageSetup page = sheet.PageSetup;
page.Orientation = Excel.XlPageOrientation.xlLandscape;
page.FitToPagesTall = false;
page.FitToPagesWide = 1;
ExcelApp.PrintCommunication = true;
Marshal.ReleaseComObject(page);

// 任意の行で改ページ
SetKaiPage(sheet, 1, 6, 1, 6);

// 任意の行で改ページ
SetKaiPage(sheet, 1, 8, 1, 8);

Book.SaveAs(@"d:\tmp\a.xlsx");
Book.Close(false, Missing.Value, Missing.Value);

ExcelApp.Quit();

Marshal.ReleaseComObject(sheet);
if (Marshal.IsComObject(sheets)) Marshal.ReleaseComObject(sheets);
Marshal.ReleaseComObject(Book);
if (Marshal.IsComObject(books)) Marshal.ReleaseComObject(books);
Marshal.ReleaseComObject(ExcelApp);
----------------------------

@関数群
----------------------------
private void SetData(Excel.Worksheet sheet, int startX, int startY, int endX, int endY, object[,] data)
{
	Excel.Range range0 = sheet.Cells;
	Excel.Range range1 = range0.Item[startY, startX];
	Excel.Range range2 = range0.Item[endY, endX];
	Excel.Range range3 = sheet.Range[range1, range2];

	range3.Value2 = data;

	Marshal.ReleaseComObject(range0);
	Marshal.ReleaseComObject(range1);
	Marshal.ReleaseComObject(range2);
	Marshal.ReleaseComObject(range3);
}

private void SetKaiPage(Excel.Worksheet sheet, int startX, int startY, int endX, int endY)
{
	Excel.Range range0 = sheet.Cells;
	Excel.Range range1 = range0.Item[startY, startX];
	Excel.Range range2 = range0.Item[endY, endX];
	Excel.Range range3 = sheet.Range[range1, range2];

	range3.PageBreak = (int)Excel.XlPageBreak.xlPageBreakManual;

	Marshal.ReleaseComObject(range0);
	Marshal.ReleaseComObject(range1);
	Marshal.ReleaseComObject(range2);
	Marshal.ReleaseComObject(range3);
}
----------------------------

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -