Excelのワークシート上にドラッグ&ドロップして配置された画像のセルのアドレスを推定するAppleScriptの強化版です。
このぐらい作り込んでおけば実用性のある部品になることでしょう。Microsoft Excel 16.76を対象に検証を行なっています。テストは1つのExcel書類上に1つだけ画像を配置(Finderからドラッグ&ドロップで配置)した状態、1つのセルの上に乗っているように見える状態に大きさを調整して実行しました。
まず、大前提でpictureのID(1から始まる通し番号)、pictureの始点座標が存在するExcel上のセルのrow(行)とcolumn(列)。これはあらかじめ各Pictureの始点座標をもとにあらかじめ計算しておいたものを使います。
本Scriptは、この「始点座標から存在するセルを計算」する処理の後処理として、実際に画像が重なっているセルを重なっている部分の面積をもとに最大の面積のものを「配置されているセル」として計算で推定します。
この処理には前提条件があって、複数のセルにまたがりすぎているような(数十のセルにまたがってpictureが配置されている)場合には計算そのものが無意味です。「1セルに1画像ぐらい」の調子で配置されていないと、こうした処理を行なっても無駄になってしまいます。
本Scriptでは、Excelワークシートの対象のpictureのID、pictureの始点座標から求めたセルのrow(行)とcolumn(列)を与えて呼び出します。すると、始点セルを基準に3×3のセルの矩形エリア(NSRect)を求め、pictureの矩形(NSRect)との重なっている面積を計算。もっとも面積が大きいものを対象セルとしてrow, columnを返します。
こうしたScriptを作ってほうがよいと考えた理由は、このExcelシート上に貼り付けた画像に対してさまざまな文字データが隣のセルに入力され、セル上のデータと画像を関連づけてデータ取得するような処理を考えたときに必要と考えたためです。
AppleScript名:pictureが置かれているセルのアドレスを推定する v2.scpt |
— – Created by: Takaaki Naganoya – Created on: 2023/08/07 — – Copyright © 2023 Piyomaru Software, All Rights Reserved — use AppleScript use scripting additions use framework "Foundation" set targRow to 22 set targCol to 2 set targPictureID to 1 set tCell to getPictureLocatedCellRowColByItsPosition(targRow, targCol, targPictureID) of me –> {rowNum:23, columnNum:2} –ループで指定セルを左上とした3×3の範囲のセルから、指定のPictureと重なっている面積が最も大きいものを返す on getPictureLocatedCellRowColByItsPosition(targRow as integer, targCol as integer, targPictureID as integer) –Picture 1のNSRectを求める set pRect to getAPictureRectByID(targPictureID) of me set tmpList to {} –始点座標から3×3の範囲のセルとPictureの重なる面積を計算 repeat with x from 0 to 2 repeat with y from 0 to 2 set tmpRow to (targRow + y) set tmpCol to (targCol + x) set tmpRect to retExcelCellRect(tmpRow, tmpCol) of me –指定Pictureと指定Cellの共通部分の矩形座標を計算 set a1Res to (current application’s NSIntersectionRect(tmpRect, pRect)) as {record, list} –指定Pictureと指定Cellの共通部分の面積を計算 set a1Area to calcAnArea(a1Res) of me if a1Area > 0 then set the end of tmpList to {columnNum:tmpCol, rowNum:tmpRow, interAreaWithPict:a1Area} end if end repeat end repeat –面積で降順ソート set zList to (sortRecListByLabel(tmpList, {"interAreaWithPict"}, {false}) of me) as list –> {{columnNum:2, rowNum:23, interAreaWithPict:4973.377807617188}, {columnNum:2, rowNum:24, interAreaWithPict:747.665495456778}, {columnNum:2, rowNum:22, interAreaWithPict:333.296168677043}} set resCell to first item of zList set resCol to columnNum of resCell set resRow to rowNum of resCell return {rowNum:resRow, columnNum:resCol} end getPictureLocatedCellRowColByItsPosition –IDで指定したPictureのNSRectを返す on getAPictureRectByID(anID as integer) tell application "Microsoft Excel" tell active workbook tell active sheet set anImage to picture anID set tmpX to left position of anImage set tmpY to top of anImage set tmpW to width of anImage set tmpH to height of anImage end tell end tell end tell set aZRect to current application’s NSMakeRect(tmpX, tmpY, tmpW, tmpH) return aZRect end getAPictureRectByID –NSRectの面積を計算する on calcAnArea(aRect) if class of aRect = list then set xWidth to (item 1 of item 2 of aRect) set yHeight to (item 2 of item 2 of aRect) else set xWidth to (aRect’s |size|’s width) set yHeight to (aRect’s |size|’s height) end if set anArea to xWidth * yHeight return anArea end calcAnArea –指定Row, ColumnのCellのNSRectを返す on retExcelCellRect(y as integer, x as integer) tell application "Microsoft Excel" tell active workbook tell active sheet tell row y tell cell x set xMin0 to left position set yMin0 to top set xWidth0 to width set yHeight0 to height end tell end tell end tell end tell end tell set a1Rect to current application’s NSMakeRect(xMin0, yMin0, xWidth0, yHeight0) return a1Rect end retExcelCellRect –リストに入れたレコードを、指定の属性ラベルの値でソート on sortRecListByLabel(aRecList as list, aLabelStr as list, ascendF as list) set aArray to current application’s NSArray’s arrayWithArray:aRecList set aCount to length of aLabelStr set sortDescArray to current application’s NSMutableArray’s new() repeat with i from 1 to aCount set aLabel to (item i of aLabelStr) set aKey to (item i of ascendF) set sortDesc to (current application’s NSSortDescriptor’s alloc()’s initWithKey:aLabel ascending:aKey) (sortDescArray’s addObject:sortDesc) end repeat return (aArray’s sortedArrayUsingDescriptors:sortDescArray) end sortRecListByLabel |