次の条件と処理方法でエクセルファイル中のオートシェイプを制御したところ、想定しない動作となり困っています。
・処理概要
次の処理中のファイルは「参考ファイル」をご覧ください。
1.page_no1.xlsxをAsposeで開く
2.最初のシートを取得
3.当該シートから名前「KSSR_S_IchigouGaikokujin_Y」が割当て済みのセルのRangeを取得
※当該セルは4つのセルをマージしたものです
4.当該RangeのGetMergedRangeメソッドでマージ済みRangeを取得
5.手順2のシートから名前「KSSR_S_IchigouGaikokujin」のShapeを取得
6.当該ShapeのX, Y, Width, Heightに対して手順4で取得したマージ済みRangeのそれらを代入
なお、ShapeのWidthの単位はピクセルでRangeのWidthの単位はポイントなので
ポイント➡ピクセルの単位換算をしています。
具体的には、CellsHelper.DPI / 72F で求まる係数をポイントに乗じてピクセルに変換しています。
・期待結果
この処理により期待する結果は次のものです:
マージ領域の縦横の4つの各辺にちょうど接するように楕円が配置される。
(EXPECTED_page_no1.xlsxもご覧ください)
・実際の結果
X, Width、Heightは期待通りになりますが、Yだけずれてしまいます。
なお、Yのずれ量はかならずしも固定ではないようです。
・質問
ユーザーコードは前述のポイント➡ピクセル換算くらいで、それ以外のロジックはありません。
AsposeのCellsライブラリの不具合か否か調査をお願いできますでしょうか?
・参考ファイル
参考情報として入力したエクセルファイルと、出力ファイルを添付します。
以下、概要です。
●page_no1.xlsx
手順1の入力ファイル
●AsposeWrapperTests_CircleArrangeTest_page_no1_20250613163354.xlsx
手順6の結果ファイル
●EXPECTED_page_no1.xlsx
期待する結果。
●page_no2.xlsx
page_no1.xlsxのバリエーションです。
操作対象のオートシェイプと配置先セルが印刷領域の2ページ目にあるものです。
page_no1.xlsxと比較して、縦のずれ量が異なる結果となりました。
@akimamura
エクセルファイル内のオートシェイプの位置に関する問題についてお答えします。あなたの処理手順を確認すると、特にY座標のずれが発生しているとのことですが、これはいくつかの要因によって引き起こされる可能性があります。
-
単位の変換: あなたが言及したように、Shapeの幅はピクセル単位で、Rangeの幅はポイント単位です。この変換が正確に行われているかを再確認してください。特に、DPIを用いた計算が正確であることを確認することが重要です。
-
マージされたセルの位置: マージされたセルの位置が正確に取得されているかどうかも確認してください。GetMergedRange
メソッドが正しい範囲を返しているか、またその範囲のY座標が正確であるかを確認することが重要です。
-
シートのスケーリング: シートのスケーリング設定が影響を与えている可能性があります。特に印刷領域やページ設定が異なる場合、Y座標の計算に影響を与えることがあります。
-
Aspose.Cellsのバージョン: 使用しているAspose.Cellsのバージョンにバグが存在する可能性も考えられます。最新のバージョンにアップデートして、問題が解決するかを確認してください。
これらの点を確認した上で、問題が解決しない場合は、Asposeのサポートチームに具体的なコードとともに問い合わせることをお勧めします。彼らはより詳細な調査を行い、必要に応じて修正や改善を提案してくれるでしょう。
添付しわすれたファイルをアップロードします。
excel-files.zip (95.7 KB)
@akimamura
サンプルファイルと実行可能なテストコードを提供しますか。エラーをスクリーンショットしてハイライト表示することができれば、問題の特定に役立ちます。私たちはすぐに検査します。
サンプルプログラムを添付します。
MoveCircles.zip (24.6 KB)
zipをunzipしてcsprojのパスにcdしてください。
そしてdotnet runしてください。
すると、bin\Debug\net8.0にresult.xlsxが作られます。
私の環境での実行結果を貼ります:
Pasted image 20250616103928.png (786 バイト)
期待する結果:
Pasted image 20250616103337.png (1.6 KB)
補足:
上のサンプルプログラムは、最初の投稿で説明した処理を簡略化したものです。
サンプルプログラムではH114のレンジを取得するところでは「名前」を使っていません。
オートシェイプの参照でのみ使っています。
@akimamura
サンプルコードとファイルを使用して最新バージョンv 25.6でテストすることで、問題を再現することができます。rangeの座標属性を使用してshapeの座標を設定していることがわかり、shapeに位置エラーが発生しました。
内部問題追跡システムで次の新しいチケットを開き、Free Support Policies に記載されている条件に従って修正を提供しています。
質問番号:CELLSNET-58595
@John.He
ご対応ありがとうございます。
こちらの都合ですが、すぐに修正プログラムを取り込むことができるか分かりません。
使用中のバージョン 24.6.0 で利用可能な回避策はないでしょうか?
たとえば、shape.Top = 0によって"snap"させようとしました。
具体的には、添付のサンプルプログラムを参照ください。
この方法だと、うまくいかないときがあります。
template1.xlsxとtemplate2.xlsxで結果が異なることを確認できると思います。
template2.xlsxは回避策として機能していますが、
template1.xlsxは回避策として機能していません。
(試すにはcsファイル中のpathのファイル名と一緒にcsproj内のファイル名も修正してください)
私の推測では、この結果の違いはshapeの原点がレンジのどこにあるのかに依存していると思っています。
MoveCirclesv2.zip (46.2 KB)
@akimamura
あなたのフィードバックに感謝します。私たちはあなたが言及した問題を再現することができます。shape.Leftとshape.Topを設定することで、一部のファイルだけを満たすことができます。私たちは問題をさらに研究し、更新があれば、すぐにお知らせします。
@akimamura
さらに検討した結果、次のサンプルコードを参考にしてニーズを実現できることがわかりました。添付ファイルを確認してください。 result.zip (46.6 KB)
//read template file.
var workbook = new Workbook("E:\\VSCellsForm\\MoveCirclesv2\\template2.xlsx");
workbook.Settings.CultureInfo = CultureInfo.GetCultureInfo("ja-JP");
var sheet = workbook.Worksheets[0];
var cell = sheet.Cells["H114"];
//H114 is merged.
var range = cell.GetMergedRange();
//get sizes.
var ptToPx = CellsHelper.DPI / 72F;
//get the merged H114 range size in points.
var rect = new RectangleF()
{
X = (float)(range.Left * ptToPx),
Y = (float)(range.Top * ptToPx),
Width = (float)(range.Width * ptToPx),
Height = (float)(range.Height * ptToPx)
};
//set the shape size and position so that it matches the merged cell H114.
var shapeName = "KSSR_S_IchigouGaikokujin";
var shape = sheet.Shapes.Where(s => s.Name == shapeName).Single();
shape.Width = (int)rect.Width;
shape.Height = (int)rect.Height;
//comment this code
//shape.Y = (int)rect.Top;
//shape.X = (int)rect.Left;
shape.Left = 0;
shape.Top = 0;
//save result files
workbook.Save("E:\\VSCellsForm\\MoveCirclesv2\\result_net2.xlsx", SaveFormat.Xlsx);
workbook.Save("E:\\VSCellsForm\\MoveCirclesv2\\result_net2.pdf", SaveFormat.Pdf);
1 Like
@John.He
ありがとうございます、参考になりました。
この考え方をベースに回避策を講じたいと思います。
@akimamura
あなたのフィードバックに感謝します。shape.Xとshape.Yは、ワークシートの左上隅を基準点としています。shape.Leftとshape.Topは、セルの左上隅を基準点としています。提案されたコードがあなたの問題を解決してくれて嬉しいです。何か質問があれば、いつでも連絡してください。
参考まで追記します。
残念ながら、提案していただいた方法では対応できないケースがありました。
最終的に、ShapeクラスのMoveToRangeを使うのが最もシンプルという結論に至りました。
なお、同種のメソッドとしてAlignTopRightCornerメソッドもありますが、
図形とセルの右上のコーナーを合わせるものなので今回の要件には適しませんでした。
@akimamura,
Shape.MoveToRangeメソッドがお客様のニーズに合っているようですので、ご活用ください。ご質問やご意見がございましたら、お気軽にお問い合わせください。