Ваша первая проблема - это Points.X & Points.Y, которые не относятся к документу или настройке отдельного монитора клиента, забудьте о настройке нескольких мониторов. Например, если курсор pos = (1000 500), но приложение не работает в полноэкранном режиме, необходимо учитывать Application.Left
/ Application.Top
значений.
Несмотря на это, это не совсем точное представление о том, где находится ваша фигура. rectang.Left / rectang.Top не относятся к электронной таблице, как вы упоминаете, они относятся к объекту электронной таблицы или окну, если хотите. Это означает, что если бы вы переместили прямоугольник полностью влево и вверх по таблице, это было бы (0,0). Как показано ниже:
Теперь, допустим, мы удаляем заголовки столбцов, а также строку формулы из объекта ActiveWindow, координаты сохраняют свою позицию, как показано ниже:
Очевидно, что размер среды приложения изменился, а не прямоугольник. Левая позиция. При этом положение курсора Application.Top + rectang.Top никогда не будет истинным представлением того, где находится верх прямоугольника, если вы не учтете все эти обстоятельства времени выполнения.
Допустим, вы учитываете это, у вас есть доступ к некоторым настройкам с помощью объекта ActiveWindow
, например Application.ActiveWindow.DisplayHeadings
, и вы действительно стараетесь, чтобы эти проблемы не возникали. У вас все еще есть куча пользовательских предпочтений, которые нужно учитывать, т.е. отображаемые полосы прокрутки для учета, вкладки, фактическая лента, которые могут быть или не быть одинакового размера для клиентов, минимизированы или развернуты, макеты страниц, каков текущий уровень масштабирования Одно только вызовет конфликты, и не забывайте о панелях контента. Давайте возьмем, к примеру, панель окна формата формы, переместив ее влево от приложения и изменив ее размер до противной ширины, определенной пользователем:
Координаты по-прежнему сохраняют свое относительное положение, которое не будет коррелировать с положением курсора независимо от того, к каким свойствам у вас есть доступ, поскольку оно всегда будет зависеть от настроек среды пользователя.
В настоящее время мой ответ будет состоять в том, чтобы сказать, что не существует разумного «готового» метода для этого, а также по другой простой причине: у объектов Shape в Excel нет обработчиков событий для таких вещей, как onclick. или иным образом, кроме Worksheet.SelectionChange
не срабатывает выбор Shapes afaik. Вы могли бы потенциально найти «хакерский» способ, запустив цикл для постоянной проверки текущего выбора и т. Д., Но, естественно, это нежелательно по соображениям производительности.
В качестве встроенного средства для достижения этой цели, до тех пор, пока для объектов Shape не будут добавлены обработчики событий, лучше всего было бы перенести это на COM AddIn или заполнить какую-то форму VBA Windows на рабочем листе, где у вас есть больше контролировать позиции клиента, все манипуляции с формой в форме, а затем добавить конечный продукт в электронную таблицу, когда пользователь будет готов.