В основе возможности реализовать непосредственный ввод «сложных» значений по введенному тексту (а ля 1С 8.х) в форме 1С 7.7 лежит баг, при котором, если в уже открытой форме выполнить метод «Форма.ТолькоПросмотр(0)», то все поля ввода (исключением являются поля ввода таблицы) становятся доступными для ввода произвольного текста.
К сожалению, 1С 7.7 не «позволяет» получить введенный текст, поэтому нам придется обратиться к некоторым хитростям.
Вооружившись славной dll «dynwrap.dll» (предварительно зарегистрировав ее «regsrv32 dynwrap.dll»), мы проделаем следующее:
- Определим «формулу» в элементе диалога «ВыбратьПоТексту()»
- В процедуре ВыбратьПоТексту()
- Получим хэндл активного окна
- Прочтем текст из него
- Обработаем текст
Собственно, это - краткие теоретические выкладки.
А вот и сам код:
//НАЧАЛО КОДА
Перем РежимРедактированияВключен;
Процедура ВыбратьПоТексту()
scrptCtrl=createobject("MSScriptControl.ScriptControl");
scrptCtrl.language="vbscript";
scrptCtrl.addcode("
|Function GetText()
|Text = Space(128)
|Set Wrapper = CreateObject(""DynamicWrapper"")
|Wrapper.Register ""USER32.DLL"", ""SendMessage"", ""I=lllr"", ""f=s"", ""r=l""
|Wrapper.Register ""USER32.DLL"", ""GetFocus"", ""f=s"", ""r=l""
|ActiveControl = Wrapper.GetFocus 'элемент окна с фокусом ввода
|tcnt = Wrapper.SendMessage (ActiveControl, &HD ,128, Text) 'WM_GETTEXT
|GetText = Text
|End Function");
Текст = scrptCtrl.run("GetText");
//простой пример обработки полученного текста
Сотрудники = СоздатьОбъект("Справочник.Сотрудники");
Сотрудники.НайтиПоНаименованию(Текст,0,0);
Сотр = Сотрудники.ТекущийЭлемент();
КонецПроцедуры
Функция ВключитьРежимРедактированияПолей()
Если РежимРедактированияВключен = 0 Тогда
Форма.ТолькоПросмотр(0);
РежимРедактированияВключен = 1;
КонецЕсли;
КонецФункции
РежимРедактированияВключен = 0;
//КОНЕЦ КОДА
пример более качественной обработки результата для 1С++, позволяющий видеть в выпадающем списке возможные варианты значений, если их несколько:
ТЗ = СоздатьОбъект("ТаблицаЗначений");
RS = СоздатьОбъект("ODBCRecordSet");
RS.ВыполнитьИнструкцию("
|select
| Сотрудники.ID [Сотрудник $Справочник.Сотрудники]
|from
| $Справочник.Сотрудники as Сотрудники
|where
| Сотрудники.DESCR like '%"+Текст+"%'",ТЗ);
СписокСотр = СоздатьОбъект("СписокЗначений");
ТЗ.Выгрузить(СписокСотр,,,"Сотрудник");
Если СписокСотр.РазмерСписка() = 1 Тогда
Сотр = СписокСотр.ПолучитьЗначение(1);
Иначе
зн = 0;
Если СписокСотр.ВыбратьЗначение(зн,,,,2) = 1 Тогда
Сотр = зн;
КонецЕсли;
КонецЕсли;
PS: Данный баг и текущий способ ввода были мною проработаны около 4-х лет назад. Я определил процеуру в глобальном модуле и в ней, используя 1С++ как источник данных, формировал выпадающий список с возможными вариантами значений по like.