Загадка

Программирование на Visual Basic for Applications
Sam777e
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 157
Зарегистрирован: 16.09.2010 (Чт) 4:33

Загадка

Сообщение Sam777e » 29.06.2016 (Ср) 11:49

Нужна была визуализация процесса решения задачи для игры Rush Hour. Хотелось, чтобы левый-верхний угол фигуры-прямоугольника совпадал с углом ячейки. С удивлением и раздражением увидел ситуацию, изображенную на картинке. Разобрался [ , но некоторое раздражение осталось ... ].

Сейчас предлагаю как маленькую задачу-курьез. Обращение к уже знающим суть/ответ - пожалуйста, проявите терпение и дайте возможность высказаться коллегам, способным подумать и разобраться.

Модераторам: если сочтете нужным, то переносите в Народный треп.
Вложения
Rush Hour.PNG
Rush Hour.PNG (31.98 Кб) Просмотров: 9182
Здоровья и удачи

Sam777e
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 157
Зарегистрирован: 16.09.2010 (Чт) 4:33

Re: Загадка и извинение

Сообщение Sam777e » 20.07.2016 (Ср) 3:09

Только сейчас заметил, что неудачно сделал картинку.

В окне Immediate первая строка была такой:

ActiveSheet.Shapes("theShape").Left = Cells(1,2).Left

Прошу извинить.

Может поэтому нет реплик от разобравшихся в ситуации?
Здоровья и удачи

Jack Ferre
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 132
Зарегистрирован: 17.02.2014 (Пн) 14:31
Откуда: Казахстан, Костанай

Re: Загадка

Сообщение Jack Ferre » 21.07.2016 (Чт) 7:28

ActiveSheet.Shapes("theShape").Left = Cells(1,2).Left * ActiveWindow.Zoom / 100

Sam777e
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 157
Зарегистрирован: 16.09.2010 (Чт) 4:33

Re: Загадка

Сообщение Sam777e » 21.07.2016 (Чт) 9:10

@Jack Ferre

Спасибо за внимание!



Однако, проверили ли Вы вашу идею?
Я не поленился, команда

ActiveSheet.Shapes("theShape").Left = Cells(1,2).Left * ActiveWindow.Zoom / 100

отработала - теперь левый край theShape оказался правее левого края Cell.

Контрольная печать дает

Код: Выделить всё
? ActiveSheet.Shapes("theShape").Left, Cells(1,2).Left
  27            13,5


Но любая идея приветствуется!
Здоровья и удачи

Jack Ferre
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 132
Зарегистрирован: 17.02.2014 (Пн) 14:31
Откуда: Казахстан, Костанай

Re: Загадка

Сообщение Jack Ferre » 21.07.2016 (Чт) 9:57

Sam777e писал(а):Однако, проверили ли Вы вашу идею?

Нет. Про зум предположил (на скриншоте большие заголовки строк/столбцов)

Нет под рукой 2003-го офиса чтобы проверить. В 2007-м такой проблемы нет.

Sam777e
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 157
Зарегистрирован: 16.09.2010 (Чт) 4:33

Re: Загадка

Сообщение Sam777e » 24.07.2016 (Вс) 14:20

У меня нет 2007-ого офиса, пошел к приятелю, открыл файл-2003.xls, ситуация прежняя ... Ну, и поскольку я знаю ответ, то выскажу осторожное предположение, что дело не в зуме и не в версии офиса.
:bom:
Здоровья и удачи

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Загадка

Сообщение pronto » 24.07.2016 (Вс) 15:44

Такой вариант пойдёт?
Код: Выделить всё
ActiveSheet.Shapes("TheShape").Left = ActiveSheet.Columns("B").Left

Или так:
Код: Выделить всё
ActiveSheet.Shapes("TheShape").Left = ActiveSheet.Columns(2).Left
ActiveSheet.Shapes("TheShape").Top = ActiveSheet.Rows(3).Top

Офис 2003
O, sancta simplicitas!

Alec
Бывалый
Бывалый
 
Сообщения: 275
Зарегистрирован: 31.08.2008 (Вс) 0:15
Откуда: Ростов-на-Дону

Re: Загадка

Сообщение Alec » 25.07.2016 (Пн) 22:29

Однако, интрига. Походу задачка сводится к тому, чтоб воспроизвести эффект... У меня так и не получилось.
Иногда лучше вовремя остановиться...
И начать заново!

Sam777e
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 157
Зарегистрирован: 16.09.2010 (Чт) 4:33

Re: Загадка

Сообщение Sam777e » 27.07.2016 (Ср) 15:30

Еще раз прошу всех извинить меня.

Я в стартовом посте выразился неточно по форме и неверно по содержанию. Не "разобрался", а добился нужного мне поведения программы - если положить n = 1000, то прямоугольник плавно едет к нужной границе ячейки [ компьютер старый и специально ( Sleep, ... ) замедлять не надо ]; Win XP SP2 Excel 2003, разрешение экрана 800х600.

После ответа Jack Ferre, на чужом компьютере [ Win XP SP3 Excel 2007, разрешение экрана забыл посмотреть ] невнимательно посидел/проверил, послал ответ ... неверный! Персональное извинение.

А вчера сидел долго и не добился желаемого, то есть волшебная строка

ActiveSheet.Shapes("theShape").DrawingObject.Left = Cells(1,2).Left

на моем компе работает, а на втором - нет.

@pronto
Мне кажется, что Ваши варианты полностью аналогичны указанному в загадке; тем не менее - проверил, результат ожидаемый.

Мелкие брызги.
Почему такой код? Прежде всего потому, что такой ...кодер.

Выяснилось немало любопытного:

1. Свойства столбца Width и ColumnWidth
одно в пикселях, другое привязано к фонту [ а если их несколько !? ]
одно можно устанавливать, другое Read Only
у обоих тип Single, но, по-моему, реально происходит какое-то округление до каких-то знаков ... [ могу и обмануть по тупости ].

2. Поэтому [ псевдоSingle ] и не пользовался IncrementLeft.

Думается, что в глубине лежат физика мониторов, метрики и прочие вещи из Windows API, толщина линий сетки и границ, ... - но я уже стар вспоминать / [ до ] изучать / разбираться ( все равно быстро забуду ) - мне бы на уровне чистого VBA и объектной модели.

Но главные вопросы:
- почему не работает Фигура.Left = Ячейка.Left ?
- почему по-разному работает Фигура.DrawingObject.Left = Ячейка.Left ?
остаются невыясненными и если кто-либо из настоящих гуру может помочь, то большая просьба - естественно, при наличии времени.

Особой любознательности и/или необходимости у меня нет, вся работа "для себя" и демонстрировать могу и в 2003-ей версии - но, вдруг, это представляет некий общий интерес.

Спасибо за внимание.

Код: Выделить всё
Public Sub Try()
  Dim dx As Single, aShape As Shape, j As Long
  Dim Ls0 As Single, Lr0 As Single, R As Range, n As Long
 
'  Columns("A:A").Width = 10
 
  Set aShape = ActiveSheet.Shapes("theShape")
  Set R = Cells(1, 2)
 
  aShape.DrawingObject.Left = 10.123456789
  Ls0 = aShape.DrawingObject.Left
'  aShape.Left = 10.123456789
'  Ls0 = aShape.Left
 
  Lr0 = R.Left
  n = 1000
  dx = (Lr0 - Ls0) / n
  Debug.Print
  Debug.Print "Columns('A:A').Width ="; Columns("A:A").Width, vbNewLine; "Ls0 ="; Ls0, "Lr0 ="; Lr0, dx
  Debug.Print "aShape.DrawingObject.Left ="; aShape.DrawingObject.Left, vbNewLine; "R.Left ="; R.Left
'  Debug.Print "aShape.Left ="; aShape.Left, vbNewLine; "R.Left ="; R.Left
 
  Debug.Print
  For j = 1 To n
    aShape.DrawingObject.Left = Ls0 + j * dx
'    DoEvents
    Debug.Print j, j * dx, Ls0 + j * dx - aShape.DrawingObject.Left, vbNewLine; String$(90, "-")
'    aShape.Left = Ls0 + j * dx
'    Debug.Print j, j * dx, Ls0 + j * dx - aShape.Left, vbNewLine; String$(90, "-")
  Next j
  Set R = Nothing
  Set aShape = Nothing
End Sub


' Win XP SP3, Excel 2007

' Font Arial Cyr 10

' Columns('A:A').Width = 58,2
' Ls0 = 10,12339              Lr0 = 58,2     4,807662
' aShape.Left = 10,12339
' R.Left = 58,2

' 1             4,80766153335571            2,33650207519531E-05
'------------------------------------------------------------------------------------------
' 2             9,61532306671143            4,76837158203125E-05
'------------------------------------------------------------------------------------------
' 3             14,4229846000671            7,10487365722656E-05
'------------------------------------------------------------------------------------------
' 4             19,2306461334229            1,62124633789063E-05
'------------------------------------------------------------------------------------------
' 5             24,0383076667786            3,76701354980469E-05
'------------------------------------------------------------------------------------------
' 6             28,8459692001343            6,29425048828125E-05
'------------------------------------------------------------------------------------------
' 7             33,65363073349              8,10623168945313E-06
'------------------------------------------------------------------------------------------
' 8             38,4612922668457            3,33786010742188E-05
'------------------------------------------------------------------------------------------
' 9             43,2689538002014            5,48362731933594E-05
'------------------------------------------------------------------------------------------
' 10            48,0766153335571            0
'------------------------------------------------------------------------------------------


' Columns('A:A').Width = 58,2
' Ls0 = 10,12339              Lr0 = 58,2     4,807662
' aShape.DrawingObject.Left = 10,1233854293823
' R.Left = 58,2
'
' 1             4,80766153335571            2,33650207519531E-05
'------------------------------------------------------------------------------------------
' 2             9,61532306671143            4,76837158203125E-05
'------------------------------------------------------------------------------------------
' 3             14,4229846000671            7,10487365722656E-05
'------------------------------------------------------------------------------------------
' 4             19,2306461334229            1,62124633789063E-05
'------------------------------------------------------------------------------------------
' 5             24,0383076667786            3,76701354980469E-05
'------------------------------------------------------------------------------------------
' 6             28,8459692001343            6,29425048828125E-05
'------------------------------------------------------------------------------------------
' 7             33,65363073349              8,10623168945313E-06
'------------------------------------------------------------------------------------------
' 8             38,4612922668457            3,33786010742188E-05
'------------------------------------------------------------------------------------------
' 9             43,2689538002014            5,48362731933594E-05
'------------------------------------------------------------------------------------------
' 10            48,0766153335571            0
'------------------------------------------------------------------------------------------
Здоровья и удачи

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Загадка

Сообщение pronto » 27.07.2016 (Ср) 16:32

Был дан ответ на это:
Хотелось, чтобы левый-верхний угол фигуры-прямоугольника совпадал с углом ячейки

А штатный телепат форума в отпуске или занят...
Кстати, какой результат ожидаемый? И что получилось?
O, sancta simplicitas!

Sam777e
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 157
Зарегистрирован: 16.09.2010 (Чт) 4:33

Re: Загадка

Сообщение Sam777e » 27.07.2016 (Ср) 19:46

@pronto
Ожидал, что поскольку "Ваши варианты полностью аналогичны указанному в загадке" моему самому первому неработающему, то фигура не окажется в нужном месте - так оно и вышло. Именно поэтому я начал искать какое-либо решение задачи и пришел к .DrawingObject ... и, при этом, ошибочно полагал, что разобрался.

Насчет Хакера согласен, он то уж точно знает и объяснит, что это было задумано и сделано по многим умным причина; но надо, чтобы у него нашлось время [ м-м-м, сомнительно ], настроение и чтобы он полагал, что подобные вещи действительно стоит знать публике.
Здоровья и удачи

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Re: Загадка

Сообщение pronto » 28.07.2016 (Чт) 1:37

Дело всё в том, что у меня фигура встала в нужное положение... Поэтому и уточнил.
O, sancta simplicitas!

Sam777e
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 157
Зарегистрирован: 16.09.2010 (Чт) 4:33

Re: Загадка

Сообщение Sam777e » 30.07.2016 (Сб) 12:22

pronto писал(а):Дело всё в том, что у меня фигура встала в нужное положение... Поэтому и

Ну и написал бы сразу об этом.

Но важно другое - сейчас есть несколько различных моделей поведения с пресловутым .Left и совершенно нет четкого понимания ситуации [ точнее - у меня нет ].
Прошу откликнувшихся сообщить / уточнить / "заполнить" известные вам клетки таблички и я ее подредактирую - а то может я что-либо не знаю или неверно понял.

Сэнсэи, где вы?
Вложения
Svodka.PNG
Svodka.PNG (16.6 Кб) Просмотров: 9001
Здоровья и удачи

Alec
Бывалый
Бывалый
 
Сообщения: 275
Зарегистрирован: 31.08.2008 (Вс) 0:15
Откуда: Ростов-на-Дону

Re: Загадка

Сообщение Alec » 31.07.2016 (Вс) 14:40

Небольшой эксперимент
Код: Выделить всё
Sub sub1()
  Dim i As Integer
  Dim l As Single
  For i = 1 To 1000
    l = i / 100
    Cells(i, 1) = l
    Shapes(1).Left = l
    Cells(i, 2) = Shapes(1).Left
    Cells(i, 3) = Shapes(1).DrawingObject.Left
    Shapes(1).DrawingObject.Left = l
    Cells(i, 4) = Shapes(1).Left
  Next i
End Sub

показывает, что:
1. При установке .Left идет округление, причем к ближайшему кратному 0.75 (эквивалентная формула ОКРУГЛ(A1/0,75;0)*0,75)
2. Чтение .Left и .DrawingObject.Left дает одинаковый результат
3. При установке .DrawingObject.Left также идет округление, но не к ближайшему, а к меньшему кратному 0.75 (формула ОКРУГЛВНИЗ(A1/0,75;0)*0,75)
Изменение разрешения экрана ничего не поменяло.
Другой эксперимент
Код: Выделить всё
Sub sub1()
  Dim i As Integer
  Dim l As Single
  For i = 1 To 1000
    Cells(1, 1).ColumnWidth = i / 100
    Cells(i, 1) = Cells(1, 2).Left
    Shapes(1).Left = Cells(1, 2).Left
    Cells(i, 2) = Shapes(1).Left
    Cells(i, 3) = Shapes(1).DrawingObject.Left
    Shapes(1).DrawingObject.Left = Cells(1, 2).Left
    Cells(i, 4) = Shapes(1).Left
  Next i
End Sub

Показывает, что при установке .ColumnWidth у ячейки, в непонятных значениях, привязанных к шрифту, ширина ячейки, в пунктах (видимо) также хранится с таким же округлением, то есть по результатам всего цикла значения .Left у второго столбца и фигуры были одинаковы.
PS. У меня Office 2002 SP3
Иногда лучше вовремя остановиться...
И начать заново!

Sam777e
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 157
Зарегистрирован: 16.09.2010 (Чт) 4:33

Re: Загадка

Сообщение Sam777e » 03.08.2016 (Ср) 23:06

@Alec. Спасибо.

Некоторые моменты.

1. Я тоже приходил к аналогичным странным - или закономерным - округлениям. Понятно, что число 1.75 не есть Long и волей-неволей приходиться принять тип Single, но, желательно, для полноты картины, сказать: внимание, не любое значение из Single можно действительно задавать / использовать, а вот только такие, которые определяются так то и так то из таких то параметров системы. [ Может это где-то и сказано // метрики твипы, API // - но я не знаю/помню; плюс, еще раз: хочется вроде бы простые вещи делать простым путем на уровне чистого VBA.] Я уже стар и многое из того, что было в голове, ушло - но нет даже ощущения, что в каких-либо книгах видел подобное разъяснение, а книги попадались и очень хорошие; снова копаться в них, к сожалению, нет возможности.

2. Так ведь в стартовом посте уже написано, что после присваивания

ActiveSheet.Shapes("theShape").Left = Cells(1,2).Left

их .Left свойства по идее должны быть равными, чтение / отладочная печать [ якобы ] указанный факт подтверждает, но грубая проза - взгляд на лист Excel 'я приводит в недоумение [ и раздражение ].
Поэтому вопрос: вот у Вас такое присваивание устанавливает фигуру в нужное место?

3. И еще: обратите внимание - округление округлением, но как понимать приведенный выше код и его результат [ здесь показаны фрагменты ]

Код: Выделить всё
  aShape.DrawingObject.Left = 10.123456789
  ...
  Debug.Print "aShape.DrawingObject.Left ="; aShape.DrawingObject.Left, ...
  ...
'  aShape.DrawingObject.Left = 10,1233854293823  ' <<<---------------

'  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  aShape.Left = 10.123456789
  ...
  Debug.Print "aShape.Left ="; aShape.Left, ...
  ...
'  aShape.Left = 10,12339  ' <<<---------------


4. Мелкие брызги:
Shapes(1).Left =...
у меня просто не идет, требуется, например,
ActiveSheet.Shapes(1).Left =...
Почему разночтение - не знаю; мне мой вариант представляется более корректным [ конечно, с With для краткости, ясности и удобства восприятия ].

С Excel 2002 не встречался, у меня 2003

Еще раз спасибо, но у меня, к сожалению, ясной картины нет.
Здоровья и удачи


Вернуться в VBA

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

    TopList  
cron