Путешествие из сантиметров в пики

Сантиметры, дюймы, строки, пики, пиксели... В Word применяется слишком много единиц и единичек измерения. Даже запомнить их сложно, не говоря уже о том, чтобы преобразовать n-ое количество дюймов в m-ое количество пикселей. Ясно, что тяжелую работу по преобразованию одной единицы измерения в другую следует поручить Visual Basic for Application, а после посмотреть, как он справится с такой работой. А справится с ней он блестяще. Если, конечно, ему немного помочь...
Для того чтобы начать поиски решения нашей "туристической" задачи, не надо рыться в словарях по математике и информатике, чтобы понять, во сколько раз такая необычная единица измерения, как строка текста, больше или меньше другой, скажем, пики. Решение подсказывает сам Word, ибо в нем существует объект Application и несколько полезных методов. Вот они:

Метод Описание
CentimetersToPoints
Метод служит для преобразования сантиметров в пиксели и возвращает результат в виде числового значения типа Single. В методе надо указать некоторую величину в сантиметрах:
Application.CentimetersToPoints (Centimeters)

InchesToPoints
Преобразует дюймы в пиксели и возвращает число типа Single. В методе указывается величина в дюймах:
Application.InchesToPoints (Inches)

LinesToPoints

Метод позволяет определить, сколько пикселей занимает указанное число строк текстового документа Microsoft Word и возвращает число типа Single. В методе указывается число строк документа:
Application.LinesToPoints (Lines)

MillimetersToPoints

Преобразует миллиметры в пиксели и возвращает число типа Single. В методе используется один аргумент, представляющий собой количество миллиметров:
Application.MillimetersToPoints (Millimeters)

PicasToPoints

Преобразует пики (типографские единицы измерения) в пиксели и возвращает число типа Single. В методе используется аргумент — количество пиков:
Application.PicasToPoints (Picas)

PointsToCentimeters

Преобразует пиксели в сантиметры и возвращает число типа Single. В методе указывается количество точек:
Application.PointsToCentimeters (Points)

PointsToInches

Используется в Microsoft Word и преобразует пиксели в дюймы и возвращает число типа Single:
Application.PointsToInches (Points)

PointsToMillimeters

Преобразует пиксели в миллиметры и возвращает число типа Single:
Application.PointsToMillimeters (Points)

PointsToPicas

Преобразует пиксели в пики и возвращает число типа Single:
Application.PointsToPicas (Points)

PointsToLines

Преобразует пиксели в строки и возвращает число типа Single:
Application.PointsToLines (Points)

Для преобразования следует воспользоваться соответствующим методом и получить результат в той единице измерения, в которой требуется по условиям задачи. Есть, правда, небольшая проблема. Далеко не в каждом случае допускается прямое преобразование.
Скажем, упомянутое в заголовке "путешествие" оказалось бы невозможным, если бы не факт, что из любой единицы измерения можно получить пиксели, а из пикселей — любую систему счисления. Например, так:
ValPoints = Application.CentimetersToPoints(ValCM)
ValPicas = Application.PointsToPicas(ValPoints)

Вот, собственно, и все преобразования. Хотя, главное еще впереди. Преобразование должно происходить с максимальным комфортом, поэтому обратимся к формам.
Создать новую форму достаточно просто: выберите команду меню Insert — UserForm и перед вами появится таинственный серый прямоугольник с черными точками. Это и есть форма, правда, пока совершенно пустая. Вместе с формой на экране появляется панель элементов управления Toolbox и окно свойств Properties.
Немного отвлекаясь от темы, отмечу, что, проектируя форму для преобразования единиц измерения, я испробовал, по меньшей мере, десяток различных конфигураций, размеров и, в конце концов, остановился на достаточно простой и удобной форме, макет которой приводится на рисунке.
В верхнем поле формы вводится исходная величина. Две группы переключателей позволяют выбрать единицу измерения исходной и итоговой величины, в нижнем поле выводится результат. Кнопка Закрыть выполняет некоторое таинственное действо, которое убирает форму Преобразование величин с экрана.
Остается привести текст программы, которая, увы, получилась довольно-таки объемной и займет-таки у вас пару вечеров для исследования. В программе встречаются довольно странные процедуры вида OptionButton10_Click(). Это не что иное, как обработчики событий. Для того чтобы их ввести, следует руководствоваться четырьмя подсказками:
1. Нажать клавишу F7, чтобы открыть модуль, связанный с формой (его создавать не надо, поскольку он создается вместе с формой). Обратный переход от модуля к форме выполняется клавишами Shift-F7.
2. Выбрать в первом раскрывающемся списке имя объекта, например, OptionsButton10.
3. Выбрать во втором раскрывающемся списке событие объекта, например, Click.
4. Ввести текст процедуры OptionsButton10_Click, как показано в следующем листинге (курсивом выделены элементы, которые следует вводить):
Private Sub OptionButton10_Click()
Rst = 4
ConvertData
End Sub

Процедура ConvertData вызывается из всех обработчиков событий — это главная процедура модуля, поскольку именно в ней выполняется преобразование одной единицы измерения в другую. Обращаю ваше внимание на довольно странное присваивание в этой процедуре: Tmp = Int(10000 * Tmp) / 10000. Оно используется для того, чтобы сократить число знаков после запятой.
Надо ли запоминать, что 10 сантиметров соответствуют 3,93700790405273 дюймам? Наверное, нет. Потому-то результат и ограничивается всего четырьмя знаками после запятой.
Dim Src As Integer
Dim Rst As Integer

Sub ConvertData()
Dim Tmp As Double
If Src = 1 Then
Select Case Rst
Case 1
TbResult.Text = TbSource.Text
Case 2 ' сантиметры в дюймы
Tmp = Val(TbSource.Text)
Tmp = Application.CentimetersToPoints(Tmp)
Tmp = Application.PointsToInches(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 3 ' сантиметры в строки
Tmp = Val(TbSource.Text)
Tmp = Application.CentimetersToPoints(Tmp)
Tmp = Application.PointsToLines(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 4 ' сантиметры в миллиметры
' попробуйте такой вариант: Tmp*10
Tmp = Val(TbSource.Text)
Tmp = Application.CentimetersToPoints(Tmp)
Tmp = Application.PointsToMillimeters(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 5 ' сантиметры в пики
Tmp = Val(TbSource.Text)
Tmp = Application.CentimetersToPoints(Tmp)
Tmp = Application.PointsToPicas(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 6 ' сантиметры в пиксели
Tmp = Val(TbSource.Text)
Tmp = Application.CentimetersToPoints(Tmp)
Tmp = Application.PicasToPoints(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
End Select
End If
If Src = 2 Then
Select Case Rst
Case 1 ' дюймы в сантиметры
Tmp = Val(TbSource.Text)
Tmp = Application.InchesToPoints(Tmp)
Tmp = Application.PointsToCentimeters(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 2 ' дюймы в дюймы
TbResult.Text = TbSource.Text
Case 3 ' дюймы в строки
Tmp = Val(TbSource.Text)
Tmp = Application.InchesToPoints(Tmp)
Tmp = Application.PointsToLines(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 4 ' дюймы в миллиметры
Tmp = Val(TbSource.Text) '
Tmp = Application.InchesToPoints(Tmp)
Tmp = Application.PointsToMillimeters(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 5 ' дюймы в пики
Tmp = Val(TbSource.Text)
Tmp = Application.InchesToPoints(Tmp)
Tmp = Application.PointsToPicas(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 6 ' дюймы в пиксели
Tmp = Val(TbSource.Text)
Tmp = Application.InchesToPoints(Tmp)
Tmp = Application.PicasToPoints(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
End Select
End If

If Src = 3 Then
Select Case Rst
Case 1 ' строки в сантиметры
Tmp = Val(TbSource.Text)
Tmp = Application.LinesToPoints(Tmp)
Tmp = Application.PointsToCentimeters(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 2 ' строки в дюймы
Tmp = Val(TbSource.Text)
Tmp = Application.LinesToPoints(Tmp)
Tmp = Application.PointsToInches(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 3 ' строки в строки
TbResult.Text = TbSource.Text
Case 4 ' строки в миллиметры
Tmp = Val(TbSource.Text) ' Tmp * 10!!
Tmp = Application.LinesToPoints(Tmp)
Tmp = Application.PointsToMillimeters(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 5 ' строки в пики
Tmp = Val(TbSource.Text)
Tmp = Application.LinesToPoints(Tmp)
Tmp = Application.PointsToPicas(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 6 ' строки в пиксели
Tmp = Val(TbSource.Text)
Tmp = Application.LinesToPoints(Tmp)
Tmp = Application.PicasToPoints(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
End Select
End If

If Src = 4 Then
Select Case Rst
Case 1 ' миллиметры в сантиметры
Tmp = Val(TbSource.Text)
' можно и так: Tmp * 10
Tmp = Application.MillimetersToPoints(Tmp)
Tmp = Application.PointsToCentimeters(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 2 ' миллиметры в дюймы
Tmp = Val(TbSource.Text)
Tmp = Application.MillimetersToPoints(Tmp)
Tmp = Application.PointsToInches(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 3 ' миллиметры в строки
Tmp = Val(TbSource.Text)
Tmp = Application.MillimetersToPoints(Tmp)
Tmp = Application.PointsToLines(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 4 ' миллиметры в миллиметры
TbResult.Text = TbSource.Text
Case 5 ' миллиметры в пики
Tmp = Val(TbSource.Text)
Tmp = Application.MillimetersToPoints(Tmp)
Tmp = Application.PointsToPicas(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 6 ' миллиметры в пиксели
Tmp = Val(TbSource.Text)
Tmp = Application.MillimetersToPoints(Tmp)
Tmp = Application.PicasToPoints(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
End Select
End If

If Src = 5 Then
Select Case Rst
Case 1 ' пики в сантиметры
Tmp = Val(TbSource.Text)
Tmp = Application.PicasToPoints(Tmp)
Tmp = Application.PointsToCentimeters(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 2 ' пики в дюймы
Tmp = Val(TbSource.Text)
Tmp = Application.PicasToPoints(Tmp)
Tmp = Application.PointsToInches(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 3 ' пики в строки
Tmp = Val(TbSource.Text)
Tmp = Application.PicasToPoints(Tmp)
Tmp = Application.PointsToLines(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 4 ' пики в миллиметры
Tmp = Val(TbSource.Text)
Tmp = Application.PicasToPoints(Tmp)
Tmp = Application.PointsToMillimeters(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 5 ' пики в пики
TbResult.Text = TbSource.Text
Case 6 ' пики в пиксели
Tmp = Val(TbSource.Text)
Tmp = Application.PicasToPoints(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
End Select
End If

If Src = 6 Then
Select Case Rst
Case 1 ' пиксели в сантиметры
Tmp = Val(TbSource.Text)
Tmp = Application.PointsToCentimeters(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 2 ' пиксели в дюймы
Tmp = Val(TbSource.Text)
Tmp = Application.PointsToInches(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 3 ' пиксели в строки
Tmp = Val(TbSource.Text)
Tmp = Application.PointsToLines(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 4 ' пиксели в миллиметры
Tmp = Val(TbSource.Text)
Tmp = Application.PointsToMillimeters(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 5 ' пиксели в пики
Tmp = Val(TbSource.Text)
Tmp = Application.PointsToPicas(Tmp)
Tmp = Int(10000 * Tmp) / 10000
TbResult.Text = Format(Tmp)
Case 6 ' пиксели в пиксели
TbResult.Text = TbSource.Text
End Select
End If
End Sub

Private Sub CommandButton1_Click()
' Закрываем форму
Me.Hide
End Sub

Private Sub OptionButton1_Click()
Src = 1
ConvertData
End Sub

Private Sub OptionButton10_Click()
Rst = 4
ConvertData
End Sub

Private Sub OptionButton11_Click()
Rst = 5
ConvertData
End Sub

Private Sub OptionButton12_Click()
Rst = 6
ConvertData
End Sub

Private Sub OptionButton2_Click()
Src = 2
ConvertData
End Sub

Private Sub OptionButton3_Click()
Src = 3
ConvertData
End Sub

Private Sub OptionButton4_Click()
Src = 4
ConvertData
End Sub

Private Sub OptionButton5_Click()
Src = 5
ConvertData
End Sub

Private Sub OptionButton6_Click()
Src = 6
ConvertData
End Sub

Private Sub OptionButton7_Click()
Rst = 1
ConvertData
End Sub

Private Sub OptionButton8_Click()
Rst = 2
ConvertData
End Sub

Private Sub OptionButton9_Click()
Rst = 3
ConvertData
End Sub

Private Sub TbSource_Change()
ConvertData
End Sub

Private Sub UserForm_Activate()
' начальные установки при активизации формы
TbSource.Text = 0
TbResult.Text = 0
Src = 1
Rst = 1
OptionButton1.Value = True
OptionButton7.Value = True
End Sub
Чтобы при открытии документа автоматически создавалась панель инструментов Преобразование, нужно ввести следующие процедуры. В них используются такие же алгоритмы, как и в прошлый раз при создании панели Синонимы, но в панель инструментов добавляется одна-единственная команда.
Sub ShowForm()
ConvertForm.Show
End Sub

Private Sub Document_Open()
On Error Resume Next
CommandBars("Преобразование").Delete
On Error GoTo 0
Application.CustomizationContext = ActiveDocument.AttachedTemplate
With CommandBars.Add("tmpconvert", Temporary:=True)
.NameLocal = "Преобразование"
.Position = msoBarFloating
With.Controls.Add(Type:=msoControlButton)
.Caption = "Преобразование"
.Style = msoButtonCaption
.OnAction = "ShowForm"
End With
.Visible = True
End With
End Sub

К вопросу о Microsoft Office 2000
Как известно, новая, девятая версия офисного пакета уже покинула порт и отправилась в широкое плавание. Один из экземпляров пришвартовался на мой жесткий диск и обосновался там настолько прочно, что от него уже и не избавиться (да и незачем).
В приложениях Microsoft Office учтены пожелания пользователей, которые пострадали-таки от нападения так называемых макро-вирусов. Стандартные настройки Word, Excel и PowerPoint таковы, что любые макросы игнорируются, — их запуск возможен лишь в том случае, если используется цифровая подпись, о которой позднее, но не здесь и не сейчас, будет рассказано. Если вы уже установили Microsoft Office 2000, то откройте диалоговое окно Security командой меню Tools — Macro — Security и выберите в нем переключатель Medium, который позволит включать и отключать макросы документа.

Жду вашей критики о том, что и как сделано неправильно, почему не работает и зачем все это нужно. Пишите.

Сергей Лосев


Компьютерная газета. Статья была опубликована в номере 42 за 1999 год в рубрике программирование :: разное

©1997-2024 Компьютерная газета