Еще раз о раскладке
Здравствуйте, уважаемая редакция! Последние полтора-два года читаю практически каждый выпуск вашей газеты, так что беру на себя смелость отнести себя к относительно продвинутым пользователям "Компьютерной газеты" :-). В этой связи хочу высказать слова благодарности всем людям, которые делают эту газету - газета интересная в целом, а не какой-то отдельной рубрикой. Материалов много, материал подается не в занудной академической манере, а вполне доступно и, вместе с тем, не плоско. Читая статью на не совсем знакомую тематику (для меня это, например, сравнительный обзор каких-нибудь железяк), не чувствуешь себя подставкой для газеты. Практически в каждом номере можно прочитать что-нибудь про железо и софт, про игры и Интернет, новости и советы, обзоры и прикладные вещи и т.п.
(c) Компьютерная газета
Не все, конечно, радужно, и можно обсуждать концепцию какой-нибудь темы или рубрики, но, на самом деле, это занятие весьма неблагодарное, потому как каждому нравится свое, а всем не угодишь (да и не нужно это :-)).
Всегда с интересом просматриваю статьи по программированию на любых языках, особенно - статьи с кодами, т.к. сам грешу Visual Basic'ом, да и просто интересуюсь. В последнее время прошла серия статей по VB for Application - весьма достойное мероприятие, т.к. пользователей MS Office - бесчисленное множество и большинству из них "советы со стороны" будут очень кстати и помогут реально облегчить различные задачи, связанные с этим пакетом. Хочется надеяться, что эта серия не оборвется вдруг (как это было с Access'ом и, по-моему, с Excel'ом с :-().
Но это все лирика :-).
В N№ 47 в рубрике "Страна советов" прочел статью "Раскладка клавиатуры. Даешь сервис!".
Хорошая статья. Нужная статья.
Сам неоднократно бывал раздражен и наказан своей невнимательностью к раскладу клавиатуры и думал всякое в адрес Microsoft. Однако дальше этого у меня дело не шло, так как с этим явлением я сталкивался не часто и для меня не составляло проблемы провести замену вручную - во-первых, потому что и по работе, и дома я крайне редко работаю с английскими текстами, а во-вторых потому, что я успевал напечатать в "нерусском" раскладе от силы три слова. Но я вполне представляю, что для людей, работающих с английскими текстами, несвоевременное переключение расклада клавиатуры может быть доброй (а, точнее, недоброй) занозой в мягких тканях.
В этом смысле постановка этой проблемы в упомянутой статье, а, главное, решение ее в этой же статье - дело безусловно благородное и ценное.
Приведенная в статье программа работает, и работает исправно, и уже в приведенном виде может, в принципе, снять известную проблему.
Но, как человек, терзаемый любопытством, я решил поводить жирным пальцем по газетным строкам, а, проанализировав программу, испытал чувство первобытного страха перед процессом программирования. Иногда понимаешь, почему неискушенным в программировании людям программисты представляются волшебниками, в крайнем случае - компьютерными шаманами.
Лично мне программа показалась очень тяжелой и громоздкой - 15 (пятнадцать) переменных плюс один динамический массив из шести элементов, пять if'ов, из них два - вложенных, выскакивающее сообщение, восемь проверок на условие - все это просто устрашает.
После того как я набрал предлагаемый в статье код и вынес на панель инструментов соответствующую ему кнопку, я обнаружил следующее: при попытке преобразовать "Ghbdtn? Vbh!" я получил "Привет? Мир!" вместо нужного "Привет, Мир!". Т.е., как и было обещано в статье, программа не преобразовывает "/" "?" английского расклада клавиатуры в "." "," русского расклада. Более того, программа также не преобразовывает ак"'" и ак"~" в рк"е" и рк"Е" соответственно (это просто не предусмотрено в коде), а при попытке нажать на кнопку макроса при отсутствии открытых документов я получил сообщение от Visual Basic'а: "Ошибка выполнения 509. Команда GetSelStartPos недоступна, поскольку окно документа не активно." Куда податься бедному крестьянину?
Кроме того, попробуйте нажать на кнопку КОПИРОВАТЬ, ВСТАВИТЬ или ВЫРЕЗАТЬ, если вы не выделили объект или не скопировали чего-нибудь в буфер - НИЧЕГО не произойдет. Никаких информационных сообщений, выпадающих окон предупреждений или угроз и прочих попыток ткнуть пользователя в его безграмотность. И это правильно, потому как задача Word - дать пользователю возможность работать с текстом, а не любоваться остроумием программистов (а задача программиста - дать пользователю простой и эффективный инструмент, а не играть с пользователем в вопрос-ответ).
В нашем случае все было по-другому - если ничего не выделять и нажать на кнопку нашего макроса, то получишь сообщение "Выделение не определено", т.е., несмотря на GetSelStartPos, дадим понять проклятому юзеру кто есть кто.
Недостатки кода в преобразовании символов не беда, т.к. один-два символа вручную "перебить" легче, чем весь ошибочный текст. Но я себе четко представляю выражение лица какого-нибудь любопытного юзера, который нажмет на заветную кнопочку при отсутствии активных документов - ведь результат явно превзойдет всякие ожидания.
С точки зрения, так сказать, принципиальной схемы предлагаемой в статье программы - она безупречна (я имею в виду блок-схему): сначала определяется множество символов английского расклада клавиатуры, затем определяется множество символов русского расклада клавиатуры, затем исходный тест перебирается посимвольно и производится замена знаков "нерусского" расклада на наш, родимый.
Но мне кажется, что можно:
- во-первых, исходить из прямого соответствия друг другу значков, нарисованных на клавишах; это даст возможность преобразований типа ак"/" в рк"." и прочих других;
- во-вторых, обойтись гораздо меньшим числом переменных и вещей, подобных признаку регистра; это сократит программу;
- в-третьих, не забивать себе голову спецсимволами; это сократит программу;
- в-четвертых, уменьшить количество if'ов, проверок на условие и функций; это сократит программу.
В результате может получиться приблизительно следующее (с построчными комментариями):
Sub ПреобразованиеТекста()
'
' Макрос "Преобразование Текста"
'
'Эта строка без комментариев.
On Error Resume Next
'Счетчик
Dim n As Integer
'Множество символов английского расклада клавиатуры
Dim strSetEng As String
'Множество символов русского расклада клавиатуры
Dim strSetRus As String
'Переменная для хранения исходной ошибочной строки
Dim strMisString As String
'Переменная для хранения текущего символа
Dim strCurrChar As String
'Переменная для хранения номера позиции текущего символа в множествах символов
Dim numChrPos As Integer
'Переменная для хранения новой строки
Dim strNewString As String
'Определили исходную ошибочную строку
strMisString = Selection.Text
'Определили оба множества символов в исходной строке
StrSetEng = "QWERTYUIOP{}ASDFGHJKL:""ZXCVBNM<>? _
qwertyuiop[]asdfghjkl;'zxcvbnm,./~'"
StrSetRus = "ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ, _
йцукенгшщзхъфывапролджэячсмитьбю.Ее"
'Цикл производит перебор символов.
For n = 1 To Len(strMisString)
'Извлекаем текущий символ.
strCurrChar = Mid(strMisString, n, 1)
'Определяем позицию текущего символа во множестве "английских символов".
numChrPos = InStr(StrSetEng, strCurrChar)
'Выясняем, принадлежит ли текущий символ к определенному нами _
множеству "английских символов". Если нет (условие при этом будет = 0) _
то оставляем его в покое.
If numChrPos <> 0 Then
'Попался вражеский символ — заменим на соответствующий наш.
strCurrChar = Mid(StrSetRus, numChrPos, 1)
End If
'Формируем символ за символом новую строку. При этом символ оставленный _
нами в покое возвращается на свою позицию.
strNewString = strNewString & strCurrChar
Next n
'Меняем старую строку на новую.
Selection.Text = strNewString
'Устраняем подстрочную красноту.
Selection.LanguageID = wdRussian
End Sub
При этом, если убрать строки комментариев, в вышеприведенной программе можно насчитать 23 строки от Sub до End Sub против 65 строк программы из обсуждаемой статьи. Предлагаемый мной макрос также не лишен недостатков, причина которых заключается в том, что в обоих раскладах клавиатуры есть одинаковые символы (например ".", "," или """), которые вводятся различными клавишами. Так что если вы при выделении ошибочно набранной строки вдруг зацепите ".", "," или """ (что вполне реально, если учесть, что вы успели нашлепать несколько абзацев в ненашем раскладе клавиатуры), то они также будут преобразованы. Однако, во-первых, оба множества символов StrSetEng StrSetRus можно изменять по своему желанию, главное - сопоставить друг другу значки на клавишах при разных раскладах клавиатуры (не забывая про Shift), а, во-вторых, если внутри цикла поменять местами StrSetEng и StrSetRus, то макрос будет делать обратное преобразование - из русского в английский (а чуть-чуть пошаманив, этот же цикл можно использовать и для несложного криптования текста :-)).
И еще одно замечание: после выполнения макроса все-таки переключите расклад клавиатуры.
С уважением Алексей Ильченко
(c) Компьютерная газета
Не все, конечно, радужно, и можно обсуждать концепцию какой-нибудь темы или рубрики, но, на самом деле, это занятие весьма неблагодарное, потому как каждому нравится свое, а всем не угодишь (да и не нужно это :-)).
Всегда с интересом просматриваю статьи по программированию на любых языках, особенно - статьи с кодами, т.к. сам грешу Visual Basic'ом, да и просто интересуюсь. В последнее время прошла серия статей по VB for Application - весьма достойное мероприятие, т.к. пользователей MS Office - бесчисленное множество и большинству из них "советы со стороны" будут очень кстати и помогут реально облегчить различные задачи, связанные с этим пакетом. Хочется надеяться, что эта серия не оборвется вдруг (как это было с Access'ом и, по-моему, с Excel'ом с :-().
Но это все лирика :-).
В N№ 47 в рубрике "Страна советов" прочел статью "Раскладка клавиатуры. Даешь сервис!".
Хорошая статья. Нужная статья.
Сам неоднократно бывал раздражен и наказан своей невнимательностью к раскладу клавиатуры и думал всякое в адрес Microsoft. Однако дальше этого у меня дело не шло, так как с этим явлением я сталкивался не часто и для меня не составляло проблемы провести замену вручную - во-первых, потому что и по работе, и дома я крайне редко работаю с английскими текстами, а во-вторых потому, что я успевал напечатать в "нерусском" раскладе от силы три слова. Но я вполне представляю, что для людей, работающих с английскими текстами, несвоевременное переключение расклада клавиатуры может быть доброй (а, точнее, недоброй) занозой в мягких тканях.
В этом смысле постановка этой проблемы в упомянутой статье, а, главное, решение ее в этой же статье - дело безусловно благородное и ценное.
Приведенная в статье программа работает, и работает исправно, и уже в приведенном виде может, в принципе, снять известную проблему.
Но, как человек, терзаемый любопытством, я решил поводить жирным пальцем по газетным строкам, а, проанализировав программу, испытал чувство первобытного страха перед процессом программирования. Иногда понимаешь, почему неискушенным в программировании людям программисты представляются волшебниками, в крайнем случае - компьютерными шаманами.
Лично мне программа показалась очень тяжелой и громоздкой - 15 (пятнадцать) переменных плюс один динамический массив из шести элементов, пять if'ов, из них два - вложенных, выскакивающее сообщение, восемь проверок на условие - все это просто устрашает.
После того как я набрал предлагаемый в статье код и вынес на панель инструментов соответствующую ему кнопку, я обнаружил следующее: при попытке преобразовать "Ghbdtn? Vbh!" я получил "Привет? Мир!" вместо нужного "Привет, Мир!". Т.е., как и было обещано в статье, программа не преобразовывает "/" "?" английского расклада клавиатуры в "." "," русского расклада. Более того, программа также не преобразовывает ак"'" и ак"~" в рк"е" и рк"Е" соответственно (это просто не предусмотрено в коде), а при попытке нажать на кнопку макроса при отсутствии открытых документов я получил сообщение от Visual Basic'а: "Ошибка выполнения 509. Команда GetSelStartPos недоступна, поскольку окно документа не активно." Куда податься бедному крестьянину?
Кроме того, попробуйте нажать на кнопку КОПИРОВАТЬ, ВСТАВИТЬ или ВЫРЕЗАТЬ, если вы не выделили объект или не скопировали чего-нибудь в буфер - НИЧЕГО не произойдет. Никаких информационных сообщений, выпадающих окон предупреждений или угроз и прочих попыток ткнуть пользователя в его безграмотность. И это правильно, потому как задача Word - дать пользователю возможность работать с текстом, а не любоваться остроумием программистов (а задача программиста - дать пользователю простой и эффективный инструмент, а не играть с пользователем в вопрос-ответ).
В нашем случае все было по-другому - если ничего не выделять и нажать на кнопку нашего макроса, то получишь сообщение "Выделение не определено", т.е., несмотря на GetSelStartPos, дадим понять проклятому юзеру кто есть кто.
Недостатки кода в преобразовании символов не беда, т.к. один-два символа вручную "перебить" легче, чем весь ошибочный текст. Но я себе четко представляю выражение лица какого-нибудь любопытного юзера, который нажмет на заветную кнопочку при отсутствии активных документов - ведь результат явно превзойдет всякие ожидания.
С точки зрения, так сказать, принципиальной схемы предлагаемой в статье программы - она безупречна (я имею в виду блок-схему): сначала определяется множество символов английского расклада клавиатуры, затем определяется множество символов русского расклада клавиатуры, затем исходный тест перебирается посимвольно и производится замена знаков "нерусского" расклада на наш, родимый.
Но мне кажется, что можно:
- во-первых, исходить из прямого соответствия друг другу значков, нарисованных на клавишах; это даст возможность преобразований типа ак"/" в рк"." и прочих других;
- во-вторых, обойтись гораздо меньшим числом переменных и вещей, подобных признаку регистра; это сократит программу;
- в-третьих, не забивать себе голову спецсимволами; это сократит программу;
- в-четвертых, уменьшить количество if'ов, проверок на условие и функций; это сократит программу.
В результате может получиться приблизительно следующее (с построчными комментариями):
Sub ПреобразованиеТекста()
'
' Макрос "Преобразование Текста"
'
'Эта строка без комментариев.
On Error Resume Next
'Счетчик
Dim n As Integer
'Множество символов английского расклада клавиатуры
Dim strSetEng As String
'Множество символов русского расклада клавиатуры
Dim strSetRus As String
'Переменная для хранения исходной ошибочной строки
Dim strMisString As String
'Переменная для хранения текущего символа
Dim strCurrChar As String
'Переменная для хранения номера позиции текущего символа в множествах символов
Dim numChrPos As Integer
'Переменная для хранения новой строки
Dim strNewString As String
'Определили исходную ошибочную строку
strMisString = Selection.Text
'Определили оба множества символов в исходной строке
StrSetEng = "QWERTYUIOP{}ASDFGHJKL:""ZXCVBNM<>? _
qwertyuiop[]asdfghjkl;'zxcvbnm,./~'"
StrSetRus = "ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ, _
йцукенгшщзхъфывапролджэячсмитьбю.Ее"
'Цикл производит перебор символов.
For n = 1 To Len(strMisString)
'Извлекаем текущий символ.
strCurrChar = Mid(strMisString, n, 1)
'Определяем позицию текущего символа во множестве "английских символов".
numChrPos = InStr(StrSetEng, strCurrChar)
'Выясняем, принадлежит ли текущий символ к определенному нами _
множеству "английских символов". Если нет (условие при этом будет = 0) _
то оставляем его в покое.
If numChrPos <> 0 Then
'Попался вражеский символ — заменим на соответствующий наш.
strCurrChar = Mid(StrSetRus, numChrPos, 1)
End If
'Формируем символ за символом новую строку. При этом символ оставленный _
нами в покое возвращается на свою позицию.
strNewString = strNewString & strCurrChar
Next n
'Меняем старую строку на новую.
Selection.Text = strNewString
'Устраняем подстрочную красноту.
Selection.LanguageID = wdRussian
End Sub
При этом, если убрать строки комментариев, в вышеприведенной программе можно насчитать 23 строки от Sub до End Sub против 65 строк программы из обсуждаемой статьи. Предлагаемый мной макрос также не лишен недостатков, причина которых заключается в том, что в обоих раскладах клавиатуры есть одинаковые символы (например ".", "," или """), которые вводятся различными клавишами. Так что если вы при выделении ошибочно набранной строки вдруг зацепите ".", "," или """ (что вполне реально, если учесть, что вы успели нашлепать несколько абзацев в ненашем раскладе клавиатуры), то они также будут преобразованы. Однако, во-первых, оба множества символов StrSetEng StrSetRus можно изменять по своему желанию, главное - сопоставить друг другу значки на клавишах при разных раскладах клавиатуры (не забывая про Shift), а, во-вторых, если внутри цикла поменять местами StrSetEng и StrSetRus, то макрос будет делать обратное преобразование - из русского в английский (а чуть-чуть пошаманив, этот же цикл можно использовать и для несложного криптования текста :-)).
И еще одно замечание: после выполнения макроса все-таки переключите расклад клавиатуры.
С уважением Алексей Ильченко
Компьютерная газета. Статья была опубликована в номере 50 за 1999 год в рубрике soft :: текст