///#undef _DEBUG
///#define _DEBUG

Перем глСписокПутейВнешнихФорм Экспорт;
Перем _РасширениеФормы;

Перем _ЗаготовкаСпискаЗначений, _ЗаготовкаТаблицыЗначений;
Перем _ЗаготовкаСпискаЗначений2, _ЗаготовкаТаблицыЗначений2;

Функция Сам(Конт) Возврат Конт; КонецФункции
Функция Этот(Конт) Возврат Конт; КонецФункции

//------------------------------------ ------------------------------------
//Конструктор()
Процедура Конструктор() Экспорт
	глСписокПутейВнешнихФорм = СоздатьОбъект("СписокЗначений");
	глСписокПутейВнешнихФорм.ДобавитьЗначение(КаталогИБ()+"ExtForms\","ExtForms");
	глСписокПутейВнешнихФорм.ДобавитьЗначение(КаталогИБ()+"ExtForms\PrnForms\","PrnForms");
	глСписокПутейВнешнихФорм.ДобавитьЗначение(КаталогПользователя(),"КаталогПользователя");
	глСписокПутейВнешнихФорм.ДобавитьЗначение(КаталогИБ(),"КаталогИБ");

	//_РасширениеФормы = СоздатьОбъект("РасширениеФормы");

	_ЗаготовкаСпискаЗначений = 0;
	_ЗаготовкаТаблицыЗначений = 0;
//	_ЗаготовкаСпискаЗначений = СоздатьОбъект("СписокЗначений");
//	_ЗаготовкаТаблицыЗначений = СоздатьОбъект("ТаблицаЗначений");
//
//	_ЗаготовкаСпискаЗначений2 = ЗначениеВСтрокуВнутр(СоздатьОбъект("СписокЗначений"));
//	_ЗаготовкаТаблицыЗначений2 = ЗначениеВСтрокуВнутр(СоздатьОбъект("ТаблицаЗначений"));

КонецПроцедуры // Конструктор

//***********************************************************************
// найти форму в каталогах внешних форм из глСписокПутейВнешнихФорм;
Функция НайтиВнешнююФорму(НазваниеФормы) Экспорт
  Перем Путь, НазваниеФайла;

  Если (Найти(НазваниеФормы,".ert")=СтрДлина(НазваниеФормы)-СтрДлина(".ert")+1)  Тогда
  	НазваниеФайла = НазваниеФормы;
  Иначе
  	НазваниеФайла = НазваниеФормы+".ert";
  КонецЕсли;

  Для Индекс=1 По глСписокПутейВнешнихФорм.РазмерСписка() Цикл
  	Строка1 = "";
    Путь = глСписокПутейВнешнихФорм.ПолучитьЗначение(Индекс, Строка1);
	//#if _DEBUG
		Сообщить("Путь к форме - "+Путь+НазваниеФайла);
	//#endif

	Если ФС.СуществуетФайл(Путь+НазваниеФайла) = 1 Тогда
		//#if _DEBUG
			Сообщить("Путь к форме - "+Путь+НазваниеФайла);
		//#endif
		Возврат Путь+НазваниеФайла;
	КонецЕсли;
  КонецЦикла;
  Возврат "";

КонецФункции //НайтиВнешнююФорму

//------------------------------------ ------------------------------------
//ОткрытьФОрму()
// Перебирает различные варианты местонахождения формы.
Процедура _ОткрытьФорму(НазваниеФормы, Параметры="", Модально=0, ВнешнийОтчет=1) Экспорт
  Перем Путь, НазваниеФайла;
  //#if _DEBUG
  	Сообщить("ОткрытьФорму: НазваниеФормы - "+НазваниеФормы);
  	Сообщить("Модально - "+Модально);
  //#endif
  //выкинуть кавычки
  НазваниеФормы = СтрЗаменить(НазваниеФормы, """", "");

  НазваниеФайла = "";
  Если ФС.СуществуетФайл(НазваниеФормы) = 1 Тогда
  	ВнешнийОтчет = 1;
	НазваниеФайла = НазваниеФормы;
  ИначеЕсли ВнешнийОтчет = 1 Тогда
	  НазваниеФайла = НайтиВнешнююФорму(НазваниеФормы);
	  Если НазваниеФайла="" Тогда
	  	ВнешнийОтчет = 0;
	  КонецЕсли;
  КонецЕсли;

  Если Модально = 0 Тогда
    Если ВнешнийОтчет = 0 Тогда
		Если Метаданные.Обработка(НазваниеФормы).Выбран() = 1 Тогда
		//#if _DEBUG
			Сообщить("Вызываю обработку "+НазваниеФормы);
		//#endif
			ОткрытьФорму("Обработка."+НазваниеФормы+"#", Параметры);
		ИначеЕсли Метаданные.Отчет(НазваниеФормы).Выбран() = 1 Тогда
		//#if _DEBUG
			Сообщить("Вызываю отчет "+НазваниеФормы);
		//#endif
			ОткрытьФорму("Отчет."+НазваниеФормы+"#", Параметры);
		Иначе
		//#if _DEBUG
			Сообщить("Не найден встроенный отчет или обработка "+НазваниеФормы);
		//#endif
		КонецЕсли;
    Иначе
	//#if _DEBUG
		Сообщить("Вызываю внешний отчет "+НазваниеФайла);
	//#endif
		ОткрытьФорму("Отчет#", Параметры, НазваниеФайла);
    КонецЕсли;
  Иначе
    Если ВнешнийОтчет = 0 Тогда
      //ОткрытьФормуМодально("Обработка."+НазваниеФайла+"#", Параметры);
		Если Метаданные.Обработка(НазваниеФормы).Выбран() = 1 Тогда
		//#if _DEBUG
			Сообщить("Вызываю обработку "+НазваниеФормы);
		//#endif
			ОткрытьФормуМодально("Обработка."+НазваниеФормы+"#", Параметры);
		ИначеЕсли Метаданные.Отчет(НазваниеФормы).Выбран() = 1 Тогда
		//#if _DEBUG
			Сообщить("Вызываю отчет "+НазваниеФормы);
		//#endif
			ОткрытьФормуМодально("Отчет."+НазваниеФормы+"#", Параметры);
		Иначе
		//#if _DEBUG
			Сообщить("Не найден встроенный отчет или обработка "+НазваниеФормы);
		//#endif
		КонецЕсли;
    Иначе
	//#if _DEBUG
		Сообщить("Вызываю внешний отчет "+НазваниеФайла);
	//#endif
      ОткрытьФормуМодально("Отчет#", Параметры, НазваниеФайла);
    КонецЕсли;
  КонецЕсли;
КонецПроцедуры // ОткрытьФОрму

////_____________________________________________________________________________
//Процедура РедакторТЗ(ТЗ, Заголовок="", Модально=0, ВнешнийОтчет=0) Экспорт
//  Перем Сп;
//
//  Сп = СоздатьОбъект("СписокЗначений");
//  Сп.Установить("ТЗ", ТЗ);
//  Сп.Установить("Заголовок", Заголовок);
//  Сп.Установить("Модально", Модально);
//
//  _ОткрытьФорму("РедакторТЗ",Сп,Модально,ВнешнийОтчет);
//
//	//ТаблицаЗначенийФорма = СоздатьОбъект("Общие.ТаблицаЗначенийФорма");
//	//ТаблицаЗначенийФорма.РедакторТЗ(Сп,Заголовок);
//
//КонецПроцедуры

// -- ADirks --
//_____________________________________________________________________________
Функция НайтиФайлВнешнегоОтчета(ИмяОтчета, Знач сзПути) Экспорт
	Перем н, Путь;

	Если ТипЗначенияСтр(сзПути) <> "СписокЗначений" Тогда
		Путь = Строка(сзПути);
		сзПути = СоздатьОбъект("СписокЗначений");
		сзПути.ДобавитьЗначение(Путь);
	КонецЕсли;

	Для н = 1 По сзПути.РазмерСписка() Цикл
		Путь = сзПути.ПолучитьЗначение(н);
		Если ПустаяСтрока(Путь) = 1 Тогда Продолжить; КонецЕсли;

		Если ФС.СуществуетФайл(Путь + ИмяОтчета + ".ert") = 1 Тогда
			Возврат Путь + ИмяОтчета + ".ert";
		КонецЕсли;
	КонецЦикла;

	Если ФС.СуществуетФайл(КаталогИБ() + ИмяОтчета + ".ert") = 1 Тогда
		Возврат КаталогИБ() + ИмяОтчета + ".ert";
	ИначеЕсли ФС.СуществуетФайл(КаталогИБ() + "ExtForms\" + ИмяОтчета + ".ert") = 1 Тогда
		Возврат КаталогИБ() + "ExtForms\" + ИмяОтчета + ".ert";
	Иначе
		Возврат "" ;
	КонецЕсли;
КонецФункции

//_____________________________________________________________________________
//Пытается найти обработку, отчет или внешний отчет с указанным именем.
// - ИмяОбработки - строка с именем обработки/отчета. Без пути и расширения. Если последний
//   символ имени обработки - "#", то обработка откроется в новом окне.
// - Параметры - Это значение будет передано в качестве параметра в обработку.
// - Модально - Если 1, то форма будет открыта модально. По умолчанию 0.
// - Внешняя - Если 1, то сначала будет произведен поиск внешней обработки, и только в случае неуспеха -
//   обработки/отчета в конфигурации.
//   Если в этом параметре передана Строка или СписокЗначений, то они рассматривается как имя каталога,
//   в катором нужно поискать первым делом.
//
//Последовательность поиска:
// Если функция вызвана из внешнего отчета
//   1) Внешний отчет в том же каталоге, что и вызывающий отчет (если он внешний)
//   2) Внешний отчет в каталоге базы данных
//   3) Внешний отчет в каталоге ExtForms
//   4) Обработка
//   5) Отчет
// Если функция вызвана из объекта конфигурации
//   1) Обработка
//   2) Отчет
//   3) Внешний отчет в том же каталоге, что и вызывающий отчет (если он внешний)
//   4) Внешний отчет в каталоге базы данных
//   5) Внешний отчет в каталоге ExtForms
//
Функция ОткрытьОбработку(Знач ИмяОбработки, Параметры, Модально, Знач Внешняя, QuietMode = 0) Экспорт
	Перем Конт, Путь, Тип;
	Перем сзПути;
	Перем Диез;

	сзПути = СоздатьОбъект("СписокЗначений");

	Если ТипЗначения(Внешняя) = 2 Тогда
		сзПути.ДобавитьЗначение(Внешняя);
		Внешняя = 1;
	ИначеЕсли ТипЗначенияСтр(Внешняя) = "СписокЗначений" Тогда
		Для н = 1 По Внешняя.РазмерСписка() Цикл
			сзПути.ДобавитьЗначение( Внешняя.ПолучитьЗначение(н) );
		КонецЦикла;
		Внешняя = 1;
	КонецЕсли;

	ИмяОбработки = СокрЛП(ИмяОбработки);
	Если Прав(ИмяОбработки, 1) = "#" Тогда
		Диез = "#";
		ИмяОбработки = Лев(ИмяОбработки, СтрДлина(ИмяОбработки) - 1);
	Иначе
		Диез = "";
	КонецЕсли;

	Если (ПустаяСтрока(Путь) = 1) И (Внешняя = 0) Тогда
		Если Метаданные.Обработка(ИмяОбработки).Выбран() = 1 Тогда
			Тип = "Обработка";
		ИначеЕсли Метаданные.Отчет(ИмяОбработки).Выбран() = 1 Тогда
			Тип = "Отчет";
		Иначе
			Тип = "ВнешнийОтчет";
			Путь = НайтиФайлВнешнегоОтчета(ИмяОбработки, сзПути);
			Если Путь = "" Тогда
				Если QuietMode = 0 Тогда
					Сообщить("Не найдена обработка '" + ИмяОбработки + "'", "!");
				КонецЕсли;
				Возврат 0;
			КонецЕсли;
		КонецЕсли;
	Иначе
		Тип = "ВнешнийОтчет";
		Путь = НайтиФайлВнешнегоОтчета(ИмяОбработки, сзПути);
		Если Путь = "" Тогда
			Если Метаданные.Обработка(ИмяОбработки).Выбран() = 1 Тогда
				Тип = "Обработка";
			ИначеЕсли Метаданные.Отчет(ИмяОбработки).Выбран() = 1 Тогда
				Тип = "Отчет";
			Иначе
				Если QuietMode = 0 Тогда
					Сообщить("Не найдена обработка '" + ИмяОбработки + "'", "!");
				КонецЕсли;
				Возврат 0;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;

	Если Тип = "ВнешнийОтчет" Тогда
		Тип = "Отчет";
		Если Модально = 0 Тогда
			Возврат ОткрытьФорму(Тип + Диез, Параметры, Путь);
		Иначе
			Возврат ОткрытьФормуМодально(Тип + Диез, Параметры, Путь);
		КонецЕсли;
	Иначе
		Если Модально = 0 Тогда
			Возврат ОткрытьФорму(Тип + "." + ИмяОбработки + Диез, Параметры);
		Иначе
			Возврат ОткрытьФормуМодально(Тип + "." + ИмяОбработки + Диез, Параметры);
		КонецЕсли;
	КонецЕсли;
КонецФункции

//_____________________________________________________________________________
//ВнешнийОтчет - м.б. числом или строкой. Если строка, то внешний отчет первым делом ищется в указанном каталоге
Процедура РедакторТЗ(Знач ТЗ, Заголовок = "", Модально = 0, Знач ВнешнийОтчет = 0, АвтоШирина = 0, ТолькоПросмотр = 0) Экспорт
	Перем Путь, Сп, Тип;

	Попытка
		ТЗ = ТЗ.ПолучитьБазовыйКласс("ТаблицаЗначений");
	Исключение
		Попытка
			ТЗ = ТЗ.ПолучитьБазовыйКласс("ИндексированнаяТаблица");
		Исключение
		КонецПопытки;
	КонецПопытки;
	Если ТипЗначенияСтр(ТЗ) = "ИндексированнаяТаблица" Тогда
		_ТЗ = СоздатьОбъект("ТаблицаЗначений");
		ТЗ.Выгрузить(_ТЗ);
		ТЗ = _ТЗ;
	КонецЕсли;

	Сп = СоздатьОбъект("СписокЗначений");
	Сп.Установить("ТЗ", ТЗ);
	Сп.Установить("Заголовок", Заголовок);
	Сп.Установить("АвтоШирина", АвтоШирина);
	Сп.Установить("ТолькоПросмотр", ТолькоПросмотр);

	Если ОткрытьОбработку("РедакторТЗ#", Сп, Модально, ВнешнийОтчет) = 0 Тогда
		//Если ТипЗначенияСтр(ТЗ) = "ТаблицаЗначений" Тогда
		//	ТЗ.ВыбратьСтроку(, Заголовок, );
		//ИначеЕсли ТипЗначенияСтр(ТЗ) = "СписокЗначений" Тогда
		//	ТЗ.ВыбратьЗначение(, Заголовок,,, 0);
		//КонецЕсли;
	КонецЕсли;
КонецПроцедуры
// -- завершение

//------------------------------------ ------------------------------------
//ПолучитьВидОбъекта(ГрупповойКонтекст Конт)
// возвращает значение в виде "Справочник.Сотрудники","Элемент.Сотрудники","Документ.АвансовыйОтчет"
// "ВнешнийОтчет.Пример.ert", "ЖурналРасчетов","ЖурналДокументов","Отчет".
// ??? для 3 последних видов и обработок не нашел способа определить вид ???
Функция ПолучитьВидОбъекта(Конт) экспорт
	Перем РасшФормы;
	Попытка
		//_РасширениеФормы.УстановитьФорму(Конт.Форма);
		РасшФормы = СоздатьОбъект("РасширениеФормы");
		РасшФормы.УстановитьФорму(Конт.Форма);
		Вид = РасшФормы.ПолныйТипОбъекта();
//Сообщить("РасшФормы.ПолныйТипОбъекта() = "+РасшФормы.ПолныйТипОбъекта());
		// c 1C++ 1.8.1.3
		Если Прав(Вид, 6) = ".Форма" Тогда
			Вид = Лев(Вид, СтрДлина(Вид)-6);
		КонецЕсли;
		Если Вид = "ВнешнийОтчет" Тогда
			Путь =""; Имя = "";
			Конт.РасположениеФайла(Путь,Имя);
			Возврат "ВнешнийОтчет."+Имя;
		КонецЕсли;
		Возврат Вид;
	Исключение
		Если ТипЗначенияСтр(Конт) = "ЖурналРасчетов" Тогда
			Возврат "ВидРасчета."+Конт.ВидРасч.Код;
		КонецЕсли;
		Попытка
			ДатаДок = Конт.НачалоИнтервала();
			Возврат "ЖурналДокументов";
		Исключение
		КонецПопытки;
		Попытка
			ДатаДок = Конт.ДатаДок;
			Возврат "Документ."+Конт.Вид();
		Исключение
		КонецПопытки;
		Попытка
			Флаг = Конт.ИерархическийСписок();
			Возврат "Справочник."+Конт.Вид();
		Исключение
		КонецПопытки;
		Попытка
			Флаг = Конт.Исправлена;
			Возврат "ЖурналРасчетов."+Конт.Вид();
		Исключение
		КонецПопытки;
		Попытка
			Флаг = Конт.Модифицированность();
			Возврат "Элемент."+Конт.Вид();
		Исключение
		КонецПопытки;
		Попытка
			Путь =""; Имя = "";
			Конт.РасположениеФайла(Путь,Имя);
			Возврат "ВнешнийОтчет."+Имя;
		Исключение
		КонецПопытки;
		Попытка
			Таб = Конт.таблица;
			Возврат "Отчет";
		Исключение
		КонецПопытки;
		Возврат "";
	КонецПопытки;
КонецФункции //ОпределитьВидОбъекта(Конт)

//------------------------------------ ------------------------------------
//void ПроверкаФормы(ГрупповойКонтекст Конт);
Процедура ПроверкаФормы(Конт) Экспорт
	Перем _РасширениеФормы;
	//#if _DEBUG
		Сообщить("Тип контекст - "+ТипЗначенияСтр(Конт));
	//#endif
	Попытка
		Форма = Конт.Форма;
	Исключение
		Возврат; // неудачно
	КонецПопытки;
	_РасширениеФормы = СоздатьОбъект("РасширениеФормы");
	_РасширениеФормы.УстановитьФорму(Конт.Форма);
	Тип = _РасширениеФормы.ТипОбъекта();
	//#if _DEBUG
		Сообщить("Тип - "+Тип);
	//#endif
	ПолныйТип = _РасширениеФормы.ПолныйТипОбъекта();
	//#if _DEBUG
		Сообщить("ПолныйТип - "+ПолныйТип);
	//#endif

КонецПроцедуры // ПроверкаФормы

//------------------------------------ ------------------------------------
//ВызовДругойФормы() - вызов дополнительной формы, возможно внешней, вместо переданной
Функция ВызовДругойФормы(Конт) Экспорт
	Перем _РасширениеФормы;
	Попытка
		Форма = Конт.Форма;
	Исключение
		Возврат 0; // неудачно
	КонецПопытки;
// тормоза
//Для к=1 По 1000000 Цикл
//КонецЦикла;
//Случай = Число(_GetPerformanceCounter()) % 10;
//Если Случай = 0 Тогда // один из трех
//	Список = СоздатьОбъект("СписокЗначений");
//	Список.ДобавитьЗначение(Список);
//	c12 = ЗначениеВСтрокуВнутр(Список);
//КонецЕсли;
	_РасширениеФормы = СоздатьОбъект("РасширениеФормы");
	_РасширениеФормы.УстановитьФорму(Форма);
	Тип = _РасширениеФормы.ТипОбъекта();
//Сообщить("Тип формы- "+ Тип);
	Если (Тип="Отчет") или (Тип="Обработка") Тогда
		ПолныйТип = _РасширениеФормы.ПолныйТипОбъекта();
//#if _DEBUG
	Сообщить("ПолныйТип формы- "+ПолныйТип);
//#endif

		// избавлюсь от возможного окончания ".Форма" (например, Отчет.СкладскойУчетМПЗ.Форма)
		лПозицияУдаления = Найти(ПолныйТип, ".Форма");
		Если лПозицияУдаления > 0 Тогда
			Если Сред(ПолныйТип, лПозицияУдаления) = ".Форма" Тогда
				ПолныйТип = Лев(ПолныйТип, лПозицияУдаления-1);
			КонецЕсли;
//#if _DEBUG
	Сообщить("ПолныйТип формы- "+ПолныйТип);
//#endif
		КонецЕсли;
		НазваниеФормы = Прав(ПолныйТип,СтрДлина(ПолныйТип)-СтрДлина(Тип)-1);
//#if _DEBUG
	Сообщить("НазваниеФормы - "+НазваниеФормы);
//#endif

		ПутьКФорме = НайтиВнешнююФорму(НазваниеФормы);
//Сообщить("ПутьКФорме - "+ПутьКФорме);

		Если ПутьКФорме <> "" Тогда
			фМодально = Конт.Форма.МодальныйРежим();
			// записал в переменную для возможного возврата параметров из формы
			лПараметрыФормы = Форма.Параметр;

			_ОткрытьФорму(ПутьКФорме, лПараметрыФормы, фМодально);

			Форма.Параметр = лПараметрыФормы;
			Возврат 1;
		КонецЕсли;
	КонецЕсли;

	Возврат 0;
КонецФункции // ВызовДругойФормы

//***********************************************************************
// добавить к кнопке на форме формулу и поменять ее название, если нужно
// СтароеНазваниеКнопки, Неопределенный НовоеНазваниеКнопки - либо строка либо СписокЗначений, из которого ищутся подходящие
// если из списка ничего не найдено, используется последнее значение.
// Если передана строка или список с одним элементом, то они используются в любом случае
  //Число УстановитьКнопкуНаФорме(ГрупповойКонтекст Конт, Строка Формула, Неопределенный СтароеНазваниеКнопки, Неопределенный НовоеНазваниеКнопки = "");
Функция УстановитьКнопкуНаФорме(Конт, Формула, СтароеНазваниеКнопки1, НовоеНазваниеКнопки1 = "") Экспорт
	Перем Список, Форма;
	Перем РасшФормы;
	//Если ТипЗначенияСтр(Конт.Форма)="НеизвестныйОбъект" Тогда // вдруг неудача
	//	Возврат 0;
	//КонецЕсли;
	Попытка
		Форма = Конт.Форма;
	Исключение
		Возврат 0; // неудачно
	КонецПопытки;
	//РасшФормы = СоздатьОбъект("РасширениеФормы");
	РасшФормы = СоздатьОбъект("РасширениеФормы");
	РасшФормы.УстановитьФорму(Форма);

	СписокСтарыхНазваний = ""; // список старых кнопок
	Если ТипЗначенияСтр(СтароеНазваниеКнопки1)="Строка" Тогда
		СписокСтарыхНазваний=СоздатьОбъект("СписокЗначений");
	 	СписокСтарыхНазваний.ДобавитьЗначение(СтароеНазваниеКнопки1);
	ИначеЕсли ТипЗначенияСтр(СтароеНазваниеКнопки1)="СписокЗначений" Тогда
	 	СписокСтарыхНазваний = СтароеНазваниеКнопки1;
	 	Если СписокСтарыхНазваний.РазмерСписка()=0 Тогда
		// 	_ВыброситьИскл("Артур.Общие УстановитьКнопкуНаФорме");
			//#curmeth
			Возврат 0;
	 	КонецЕсли;
	Иначе // ошибочный параметр
	// 	_ВыброситьИскл("Артур.Общие УстановитьКнопкуНаФорме");
		//#curmeth
		Возврат 0;
	КонецЕсли;

	//СписокНовыхНазваний = ""; // список старых кнопок
	СписокНовыхНазваний=СоздатьОбъект("СписокЗначений");
	Если ТипЗначенияСтр(НовоеНазваниеКнопки1)="Строка" Тогда
		//СписокНовыхНазваний=СоздатьОбъект("СписокЗначений");
	 	СписокНовыхНазваний.ДобавитьЗначение(НовоеНазваниеКнопки1);
	ИначеЕсли ТипЗначенияСтр(НовоеНазваниеКнопки1)="СписокЗначений" Тогда
	 	СписокНовыхНазваний = НовоеНазваниеКнопки1;
	 	Если СписокНовыхНазваний.РазмерСписка()=0 Тогда
		// 	_ВыброситьИскл("Артур.Общие УстановитьКнопкуНаФорме");
			//#curmeth
			Возврат 0;
	 	КонецЕсли;
	//Иначе // ошибочный параметр
	//// 	_ВыброситьИскл("Артур.Общие УстановитьКнопкуНаФорме");
	//	//#curmeth
	//	Возврат 0;
	КонецЕсли;
    //ФлагУстановкиКнопки = 0;
	Для Индекс=1 По СписокСтарыхНазваний.РазмерСписка() Цикл
		Строка1 = "";
		СтароеНазваниеКнопки = СписокСтарыхНазваний.ПолучитьЗначение(Индекс,Строка1);
		р = РасшФормы.НайтиАтрибут(2,СтароеНазваниеКнопки);
		//Если (р = 0) и (Индекс<СписокСтарыхНазваний.РазмерСписка()) Тогда // не нашли, перейти к следующему названию
		Если (р = 0) Тогда // не нашли, перейти к следующему названию
			Продолжить;
		Иначе
			СпецКнопка = РасшФормы.ТекущийАтрибут();
	// установить по вертикали также как кнопки Закрыть или ОК
	// по горизонтали возле правой границы формы
			р = РасшФормы.НайтиАтрибут(2,"&Закрыть");
			Если р=0 Тогда р = РасшФормы.НайтиАтрибут(2,"Закрыть"); КонецЕсли;
			Если р=0 Тогда р = РасшФормы.НайтиАтрибут(2,"ОК"); КонецЕсли;

			кнЗакрыть1 = РасшФормы.ТекущийАтрибут();
			Лев1=0;Ширина=0;Верх=0;Высота=0;

			//кнЗакрыть1.УстановитьАтрибут(Форма,кнЗакрыть1.Идентификатор);
			кнЗакрыть1.ПолучитьКоординаты(Лев1,Верх,Ширина,Высота);
			//#if _DEBUG
				//Сообщить("Координаты - "+Лев1+" - "+Верх+" - "+Ширина+" - "+Высота);
			//#endif

			Ширина=110;
			Лев1=РасшФормы.Ширина - Ширина - 4;
			//#if _DEBUG
				//Сообщить("Координаты формы - "+РасшФормы.Ширина+" - "+РасшФормы.Высота);
			//#endif
			//Ширина = РасшФормы.Ширина - 230;
			//Лев1 = Ширина - 55;
			//Если (ПустоеЗначение(НовоеНазваниеКнопки)=0) и (НовоеНазваниеКнопки<>"") Тогда
			//	СпецКнопка.Заголовок = НовоеНазваниеКнопки;//"Доп. действия...";
			//КонецЕсли;
// если кнопка с новым названием уже есть, то ищем следующую. В случае неуспеха поиска выбираем последнее название
			Для Индекс1=1 По СписокНовыхНазваний.РазмерСписка() Цикл
				Строка1 = "";
				НовоеНазваниеКнопки = СписокНовыхНазваний.ПолучитьЗначение(Индекс1,Строка1);
				Если (ПустоеЗначение(НовоеНазваниеКнопки)=0) и (НовоеНазваниеКнопки<>"") Тогда
					Если Индекс1 < СписокНовыхНазваний.РазмерСписка() Тогда
						Если (РасшФормы.НайтиАтрибут(2,новоеНазваниеКнопки)=0) или (СпецКнопка.Заголовок = НовоеНазваниеКнопки) Тогда
							СпецКнопка.Заголовок = НовоеНазваниеКнопки;//"Доп. действия...";
						    //ФлагУстановкиКнопки = 1;
							Прервать;
						КонецЕсли;
					иначе
						СпецКнопка.Заголовок = НовоеНазваниеКнопки;//"Доп. действия...";
						Прервать;
					КонецЕсли;
				КонецЕсли;
			КонецЦикла;
// !!! в 1С++ 1.7.0 и выше неверно работает !!!	!!!
//			СпецКнопка.УстановитьКоординаты(Лев1,Верх,Ширина,Высота);
			//Сообщить("Координаты - "+Лев1+" - "+Верх+" - "+Ширина+" - "+Высота);
// --------------------- --------------------- --------------------- ---------------------
			СпецКнопка.Видимость = 1;
			СпецКнопка.Доступность = 1;
			СпецКнопка.Формула = Формула;
			Возврат 1;
		КонецЕсли;
	КонецЦикла; // СписокСтарыхНазваний
    Возврат 0;
КонецФункции //УстановитьКнопкуНаФорме

////***********************************************************************
//// добавить к кнопке на форме вызов меню
//// СтароеНазваниеКнопки, Неопределенный НовоеНазваниеКнопки - либо строка либо СписокЗначений, из которого ищутся подходящие
//// если из списка ничего не найдено, используется последнее значение.
//// Если передана строка или список с одним элементом, то они используются в любом случае
////	Число ЗаменитьКнопкуНаФорме(ГрупповойКонтекст Конт, Строка Формула, Неопределенный СтароеНазваниеКнопки, Неопределенный НовоеНазваниеКнопки = "");
//Функция ЗаменитьКнопкуНаФорме(Конт, Формула, СтароеНазваниеКнопки, НовоеНазваниеКнопки = "") Экспорт
//	Попытка
//		Форма = Конт.Форма;
//	Исключение
//		Возврат 0; // неудачно
//	КонецПопытки;
//	РасшФормы = СоздатьОбъект("РасширениеФормы");
//	РасшФормы.УстановитьФорму(Форма);
//
//	р = РасшФормы.НайтиАтрибут(2,СтароеНазваниеКнопки);
//	Если р = 1 Тогда
//		СпецКнопка = РасшФормы.ТекущийАтрибут();
//		Если (ПустоеЗначение(НовоеНазваниеКнопки)=0) и (НовоеНазваниеКнопки<>"") Тогда
//			СпецКнопка.Заголовок = НовоеНазваниеКнопки;//"Доп. действия...";
//			//#if _DEBUG
//			//#endif
//			СпецКнопка.Видимость = 1;
//			СпецКнопка.Доступность = 1;
//			СпецКнопка.Формула = Формула;
//			Возврат 1;
//		КонецЕсли;
//	КонецЕсли;
//    Возврат 0;
//КонецФункции //ЗаменитьКнопкуНаФорме

//------------------------------------ ------------------------------------
//СуществуетКнопкаНаФорме(Конт,Название1, фПоИдентификатору=0)
// Название - либо строка либо СписокЗначений, из которого ищутся подходящие
// если из списка ничего не найдено, используется последнее значение.
// Если передана строка или список с одним элементом, то они используются в любом случае
// фПоИдентификатору = 1, ищем по идентификатору, 0 - по названию
// возвращает: 1 - кнопка существует, 0 - нет
Функция СуществуетКнопкаНаФорме(Конт,Название1, фПоИдентификатору) Экспорт
	Перем РасшФормы;
	Попытка
		Форма = Конт.Форма;
	Исключение
		Возврат 0; // неудачно
	КонецПопытки;

	СписокНазваний = ""; // список старых кнопок
	Если ТипЗначенияСтр(Название1)="Строка" Тогда
		СписокНазваний=СоздатьОбъект("СписокЗначений");
	 	СписокНазваний.ДобавитьЗначение(Название1);
	ИначеЕсли ТипЗначенияСтр(Название1)="СписокЗначений" Тогда
	 	СписокНазваний = Название1;
	 	Если СписокНазваний.РазмерСписка()=0 Тогда
		// 	_ВыброситьИскл("Артур.Общие УстановитьКнопкуНаФорме");
			//#curmeth
			Возврат 0;
	 	КонецЕсли;
	Иначе // ошибочный параметр
	// 	_ВыброситьИскл("Артур.Общие УстановитьКнопкуНаФорме");
		//#curmeth
		Возврат 0;
	КонецЕсли;

	РасшФормы = СоздатьОбъект("РасширениеФормы");
	РасшФормы.УстановитьФорму(Форма);

	Попытка
		Для Индекс=1 По СписокНазваний.РазмерСписка() Цикл
			Строка1 = "";
			Название = СписокНазваний.ПолучитьЗначение(Индекс,Строка1);
			Если фПоИдентификатору = 1 Тогда
				р = РасшФормы.ПолучитьАтрибут(Название);
//Сообщить("р.Наименование = <"+р.Наименование+">");
				Возврат 1;
			Иначе
				р = РасшФормы.НайтиАтрибут(2,Название);
				Если (р = 1) Тогда // не нашли, перейти к следующему названию
//Сообщить("РасшФормы.ТекущийАтрибут.Наименование = <"+РасшФормы.ТекущийАтрибут.Наименование+">");
					Возврат 1;
				КонецЕсли;
			КонецЕсли;
			//Возврат 1;
		КонецЦикла;
	Исключение
		Возврат 0;
	КонецПопытки;
    Возврат 0;

КонецФункции // СуществуетКнопкаНаФорме

// глМаксимизироватьОкно - делает сабж для любого окна
// выполняю через вызов меню программы
// вызывать в конце процедуры "ПриОткрытии" из модуля формы
Процедура глМаксимизироватьОкно() Экспорт
	WSHShell = "";
	Попытка
		WSHShell = СоздатьОбъект("WScript.Shell");
	Исключение
		Сам(Контекст)._ВыброситьИскл("Не установлен Windows Scripting Host");
	КонецПопытки;
	wshShell.appActivate("1C:Предприятие");
	WSHShell.SendKeys("%");
	WSHShell.SendKeys("{LEFT}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{ENTER}");
	WSHShell = "";
КонецПроцедуры //глМаксимизироватьОкно

//------------------------------------ ------------------------------------
//УстановитьМасштаб() - установить масштаб печатной формы.
// выполняю через вызов меню программы
// Параметры: Масштаб - 50,75.100.125.150.200 %%
Процедура УстановитьМасштаб(Масштаб) Экспорт
	Перем Список;
	Список=СоздатьОбъект("СписокЗначений");
 	Список.ДобавитьЗначение(50,"");
 	Список.ДобавитьЗначение(75,"{DOWN}");
 	Список.ДобавитьЗначение(100,"{DOWN}{DOWN}");
 	Список.ДобавитьЗначение(125,"{DOWN}{DOWN}{DOWN}");
 	Список.ДобавитьЗначение(150,"{DOWN}{DOWN}{DOWN}{DOWN}");
 	Список.ДобавитьЗначение(200,"{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}");

 	Строка1 = "";
 	Поз = Список.НайтиЗначение(Масштаб);
 	Если Поз<>0 Тогда
	 	Список.ПолучитьЗначение(Поз,Строка1);
// т.к. не нашел способа вызвать метод и для максимизированного окна, и для обычного окна
// решил автоматом максимизировать
		глМаксимизироватьОкно();

		WSHShell = "";
		Попытка
			WSHShell = СоздатьОбъект("WScript.Shell");
		Исключение
			Сам(Контекст)._ВыброситьИскл("Не установлен Windows Scripting Host");
		КонецПопытки;
		wshShell.appActivate("1C:Предприятие");
//Сообщить("АРтур.Общие.УстановитьМасштаб = ");
		WSHShell.SendKeys("%"); // системное меню
		WSHShell.SendKeys("%"); // системное меню
		WSHShell.SendKeys("%"); // системное меню
//Возврат;
		WSHShell.SendKeys("{LEFT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}");
		WSHShell.SendKeys("{DOWN}{UP}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}{DOWN}");
		WSHShell.SendKeys("{RIGHT}");
// дошли до масштаба - стоим на 50%
		WSHShell.SendKeys(Строка1);
		WSHShell.SendKeys("{ENTER}");
		WSHShell = "";
	КонецЕсли;
	Список = "";
КонецПроцедуры // УстановитьМасштаб

//ЗакрытьОкноСообщений - закрывает окно сообщений
Процедура ЗакрытьОкноСообщений() Экспорт
	wshShell = CreateObject("wScript.shell");
	wshShell.appActivate("1C:Предприятие");
	wshShell.sendKeys("^+(z)");
	wshShell.sendKeys("^+(я)");
	wshShell = "";
КонецПроцедуры //ЗакрытьОкноСообщений

//------------------------------------ -------------------------------------------------------------
// Обновление внешнего отчета с автоматическим его закрытием и открытием в новом окне
//	void ПерезагрузитьОтчет(ГрупповойКонтекст Конт);
// Пример вызова из внешнего отчета:
// об = СоздатьОбъект("Артур.Общие"); об.ПерезагрузитьОтчет(Контекст,РасположениеФайла()); об = "";
Процедура ПерезагрузитьОтчет(Конт) Экспорт
	//Тип = Сам(Контекст).ПолучитьВидОбъекта(Конт);
	//Если Найти(Тип,"ВнешнийОтчет.")=1 Тогда
	//	Путь="";Имя="";
	//	РасположениеФайла = Конт.РасположениеФайла(Путь,Имя);
	//	ОткрытьФорму("Отчет"+Симв(35),,РасположениеФайла);
	//	Конт.Форма.Закрыть(0);
	//КонецЕсли;
	Путь="";Имя="";
	Попытка
		РасположениеФайла = Конт.РасположениеФайла(Путь,Имя);
		ОткрытьФорму("Отчет"+Симв(35),,РасположениеФайла);
		Конт.Форма.Закрыть(0);
	Исключение
	КонецПопытки;
КонецПроцедуры // ПерезагрузитьОтчет
// -------------------------------------------------------------------------------------------------

//_____________________________________________________________________________
Функция ПроверкаУсловия(Знач Конт,Знач Условие) Экспорт
	// данная функция получает некую строку-условие вида "Количество<>0" и
	// ссылку на документ/справочник (контекст) или переменная-значение.
	// Если указанное условие выполняется функция возвращает число 1, иначе число 0.

	// В переменную Конт может передаваться не только контекст, но и собственно проверяемое
	// значение (переменная), например, глПроверкаУсловия(ЗначВвода,"ЗначВвода>2")

	// Типы возможный условий:
	// Равно	"="		Например "Курс=1"
	// Меньше	"<"		Например "Курс<1"
	// Больше	">"		Например "Курс>1"
	// БольшеИлиРавно	">="		Например "Курс>=1"
	// МеньшеИлиРавно	"<="		Например "Курс<=1"
	// Не равно	"<>"	Например "Курс<>1"
	// Не пусто	"#"		Например "Курс#"
	// Пусто	"!#"	Например "Курс!#"
	// Прим.: следует учитывать передачу синонимов, например: "Курс|Курс валюты>1"

	Перем ИмяРеквизита, ТипУсловия, КонтрольноеЗначение;
	Перем Равно, Меньше, Больше, БольшеИлиРавно, МеньшеИлиРавно, НеРавно, НеПусто, Пусто;

	// Устанавливаем начальные значения
	ИмяРеквизита = "";
	ТипУсловия = "";
	КонтрольноеЗначение = "";

	Равно = "=";
	Меньше = "<";
	Больше = ">";
	БольшеИлиРавно = ">=";
	МеньшеИлиРавно = "<=";
	НеРавно = "<>";
	НеПусто = "#";
	Пусто = "!#";

	// переданное разбираем условие и выделяем имя контролируемого реквизита
	Условие = СокрЛП(Условие);
	Если Найти(Условие,"!#")<>0 Тогда		// пусто
		Позиция = Найти(Условие,"!#");
	ИначеЕсли Найти(Условие,"#")<>0 Тогда		// не пусто
		Позиция = Найти(Условие,"#");
	ИначеЕсли Найти(Условие,"<>")<>0 Тогда		// не равно
		Позиция = Найти(Условие,"<>");
	ИначеЕсли Найти(Условие,"<")<>0 Тогда		// меньше
		Позиция = Найти(Условие,"<");
	ИначеЕсли Найти(Условие,">")<>0 Тогда		// больше
		Позиция = Найти(Условие,">");
	ИначеЕсли Найти(Условие,"=")<>0 Тогда			// равно
		Позиция = Найти(Условие,"=");
	Иначе
		Сообщить("Некорректный синтаксис при проверке корректности заполнения реквизитов документа/справочника - не указано условие");
		Возврат 0;
	КонецЕсли;

	// получаем имя реквизита
	ИмяРеквизита = СокрЛП(Лев(Условие,Позиция-1));
	ХвостУсловия = СокрЛ(Сред(Условие,Позиция));
	// отделяем синоним
	Позиция = Найти(Условие,"|");
	Если Позиция<>0 Тогда
		ИмяРеквизита = СокрЛП(Лев(Условие,Позиция-1));
	КонецЕсли;

	// проверим, что осталось
	Если СтрДлина(ИмяРеквизита)=0 Тогда
		Сообщить("Некорректный синтаксис при проверке корректности заполнения реквизитов документа/справочника - не указан реквизит");
		Возврат 0;
	КонецЕсли;

	// сразу же проверим, если условие - "пустое/непустое значение"
	Попытка
		Если ТипЗначения(Конт)<10 Тогда // число, дата
			ЗначениеРеквизита = Конт;
		Иначе
			ЗначениеРеквизита = Конт.ПолучитьАтрибут(ИмяРеквизита);
			Если ТипЗначенияСтр( ЗначениеРеквизита) = "Счет" Тогда
				ЗначениеРеквизита = ЗначениеРеквизита.ТекущийСчет();
			КонецЕсли;
		КонецЕсли;
	Исключение
		Возврат 0;
	КонецПопытки;

	Если Найти(Условие,"!#")<>0 Тогда
		Возврат ПустоеЗначение(ЗначениеРеквизита);
	ИначеЕсли Найти(Условие,"#")<>0 Тогда
		Возврат 1-ПустоеЗначение(ЗначениеРеквизита);
	КонецЕсли;

	// Далее - для условий "больше", "меньше", "равно", "не равно"

	// теперь разбираем хвост начального условие и выделяем
	// тип условия и контрольное значение
	Для Сч = 1 По СтрДлина(ХвостУсловия) Цикл
		ТекущийСимвол = Сред(ХвостУсловия,Сч,1);
		Если Найти("=<>",ТекущийСимвол)<>0 Тогда
		    ТипУсловия = ТипУсловия + ТекущийСимвол;
		Иначе
			КонтрольноеЗначение = СокрЛП(Сред(ХвостУсловия,Сч));
			Если Лев(КонтрольноеЗначение,1) = "'" Тогда // это дата
				КонтрольноеЗначение = Дата(Сред(КонтрольноеЗначение,2));
			Иначе // число
				КонтрольноеЗначение = Число(КонтрольноеЗначение);
			КонецЕсли;
			Прервать;
		КонецЕсли;
	КонецЦикла;

	// проверим выполнение условия
	Если (ТипУсловия=Равно) и (ЗначениеРеквизита=КонтрольноеЗначение) Тогда
		Возврат 1;
	ИначеЕсли (ТипУсловия=БольшеИлиРавно) и (ЗначениеРеквизита>=КонтрольноеЗначение) Тогда
		Возврат 1;
	ИначеЕсли (ТипУсловия=МеньшеИлиРавно) и (ЗначениеРеквизита<=КонтрольноеЗначение) Тогда
		Возврат 1;
	ИначеЕсли (ТипУсловия=Больше) и (ЗначениеРеквизита>КонтрольноеЗначение) Тогда
		Возврат 1;
	ИначеЕсли (ТипУсловия=Меньше) и (ЗначениеРеквизита<КонтрольноеЗначение) Тогда
		Возврат 1;
	ИначеЕсли (ТипУсловия=НеРавно) и (ЗначениеРеквизита<>КонтрольноеЗначение) Тогда
		Возврат 1;
	Иначе
		Возврат 0;
	КонецЕсли;
КонецФункции //глПроверкаУсловия
// ========================================================================

// -------------------------------------------------------------------------------------------------
// Перекинуть таблицу отчета в Excel и открыть его там
// void ТаблицуОтчетаВExcel(Таблица Таб, Строка ИмяФайла="", Строка ИмяКаталога="");
// 25,09,2003
Процедура ТаблицуОтчетаВExcel(Таб, ИмяФайла, ИмяКаталога) Экспорт
	// если не заданы имя файла и каталога
	ВременныйФайл = КаталогВременныхФайлов() + "art_report05798.xls";

	Если ПустаяСтрока(ИмяКаталога)=1 Тогда
		ИмяКаталога = КаталогИБ() + "Отчеты XLS";
	КонецЕсли;
	ФлагУдаления = 0;
	Если ПустаяСтрока(ИмяФайла)=1 Тогда
		Путь = ВременныйФайл;
		ФлагУдаления = 1;
	    Таб.Записать(Путь,1);
	Иначе
		Путь = ИмяКаталога + "\" + ИмяФайла;
		Если ФС.СуществуетФайл(ИмяКаталога) = 1 Тогда
	    	ФС.СоздатьКаталог(ИмяКаталога);
	    	//Таб.Записать(Путь,"xls");
		КонецЕсли;
    	Таб.Записать(Путь,1);
	КонецЕсли;

  Excel = CreateObject("Excel.Application");
  Excel.Workbooks.Open(Путь,0);
  // wb = xl.ActiveWorkbook;
  Excel.Visible = 1;
КонецПроцедуры //ТаблицуОтчетаВExcel
//_____________________________________________________________________________

// -------------------------------------------------------------------------------------------------
Процедура ПриостановитьВыполнение(СекЖдать=0,МожноПрервать=0,Сообщение="Ждите ...")
     Перем ч,м,с;
     ТекущееВремя(ч,м,с);
     ТекСек=(ч*3600)+(м*60)+с;
     КонСек=ТекСек+СекЖдать;
     Пока СекЖдать>0 Цикл
          Предупреждение(Сообщение,СекЖдать);
          Если (МожноПрервать<>0) тогда
               Прервать;
          КонецЕсли;
          ТекущееВремя(ч,м,с);
          ТекСек=(ч*3600)+(м*60)+с;
          СекЖдать=Макс(КонСек-ТекСек,0);
     КонецЦикла;
КонецПроцедуры // ПриостановитьВыполнение

//******************************************************************************
// ПредставлениеДокумента(Док, ФорматПредставления)
//
// Параметры:
//  Док - переменная типа документ или контекст документа
//  ФорматПредставления - способ отображения представления переданного документа.
//   0 или "Краткий"     - в виде "ВидДокумента ¦НомерДокумента",
//   1 или "Полный"      - в виде "ВидДокумента ¦НомерДокумента от ДД.ММ.ГГГГг."
//   2 или "НомерДата"   - в виде "¦НомерДокумента от ДД.ММ.ГГГГг."
//   3 или "Расширенный" - в виде "КомментарийВидаДокумента ¦НомерДокумента от ДД.ММ.ГГГГг."
//   4 или "ПредставлениеВида" - в виде "ВидДокумента"
//   Значение по умолчанию - 1.
//
// Возвращаемое значение:
//  Строка с представлением документа.
//
Функция ПредставлениеДокумента(Док, ФорматПредставления = 1) Экспорт

	ДокСтр = "<???>";
	Если (ТипЗначенияСтр(Док) = "Документ") или (ТипЗначенияСтр(Док) = "ГрупповойКонтекст") Тогда

		//Если Док.Выбран() = 1 Тогда

			ПредставлениеВида = Док.ПредставлениеВида();

			Если (ФорматПредставления = 0) или (ВРег(ФорматПредставления) = ВРег("Краткий")) Тогда

				ДокСтр = ПредставлениеВида;
				ДокСтр = ДокСтр + " ¦" + СокрЛП(Док.НомерДок);

			ИначеЕсли (ФорматПредставления = 1) или (ВРег(ФорматПредставления) = ВРег("Полный")) Тогда

				ДокСтр = ПредставлениеВида;
				ДокСтр = ДокСтр + " ¦" + СокрЛП(Док.НомерДок);
				ДокСтр = ДокСтр + " от " + Формат(Док.ДатаДок, "Д ДДММГГГГ") + "г.";

			ИначеЕсли (ФорматПредставления = 2) или (ВРег(ФорматПредставления) = ВРег("НомерДата")) Тогда

				ДокСтр = "¦" + СокрЛП(Док.НомерДок);
				ДокСтр = ДокСтр + " от " + Формат(Док.ДатаДок, "Д ДДММГГГГ") + "г.";

			ИначеЕсли (ФорматПредставления = 3) или (ВРег(ФорматПредставления) = ВРег("Расширенный")) Тогда

				Комментарий = Метаданные.Документ(Док.Вид()).Комментарий;

				Если ПустоеЗначение(Комментарий) = 0 Тогда
					ДокСтр = Комментарий;
				Иначе
					ДокСтр = ПредставлениеВида;
				КонецЕсли;

				ДокСтр = ДокСтр + " ¦" + СокрЛП(Док.НомерДок);
				ДокСтр = ДокСтр + " от " + Формат(Док.ДатаДок, "Д ДДММГГГГ") + "г.";

			ИначеЕсли (ФорматПредставления = 4) или (ВРег(ФорматПредставления) = ВРег("ПредставлениеВида")) Тогда

				ДокСтр = ПредставлениеВида;

			Иначе

				Сообщить("Ошибка в функции ПредставлениеДокумента. Неверно указан формат.", "!");

			КонецЕсли;

		//Иначе
        //
		//	ДокСтр = "";
        //
		//КонецЕсли;

	Иначе

		Сообщить("Ошибка в функции ПредставлениеДокумента(). Неверный тип значения.", "!");

	КонецЕсли;

	Возврат ДокСтр;

КонецФункции // ПредставлениеДокумента

//******************************************************************************
// ПредставлениеСправочника(Спр, ФорматПредставления)
//
// Параметры:
//  Спр - переменная типа справочник или контекст справочника
//  ФорматПредставления - способ отображения представления переданного документа.
//   0 или "Краткий"     - в виде "ВидСправочника ИмяЭлемента",
//   1 или "Полный"      - в виде "ВидСправочника ИмяЭлемента ( ¦НомерЭлемента )"
//   2 или "ИмяКод"   	 - в виде "ИмяЭлемента ( ¦НомерЭлемента )"
//   3 или "Расширенный" - в виде "КомментарийВидаСправочника ИмяЭлемента ( ¦НомерЭлемента )"
//   4 или "ПредставлениеВида" - в виде "ВидСправочника"
//   Значение по умолчанию - 1.
//
// Возвращаемое значение:
//  Строка с представлением документа.
//
Функция ПредставлениеСправочника(Спр, ФорматПредставления = 1) Экспорт

	ДокСтр = "<???>";
	Если (ТипЗначенияСтр(Спр) = "Справочник") или (ТипЗначенияСтр(Спр) = "ГрупповойКонтекст") Тогда

		Если Спр.Выбран() = 1 Тогда

			ПредставлениеВида = Спр.ПредставлениеВида();

			Если (ФорматПредставления = 0) или (ВРег(ФорматПредставления) = ВРег("Краткий")) Тогда

				ДокСтр = ПредставлениеВида;
				ДокСтр = ДокСтр + " " + СокрЛП(Спр.Наименование);

			ИначеЕсли (ФорматПредставления = 1) или (ВРег(ФорматПредставления) = ВРег("Полный")) Тогда

				ДокСтр = ПредставлениеВида;
				ДокСтр = ДокСтр + " ¦" + Строка(Спр.Код);
				ДокСтр = ДокСтр + " " + СокрЛП(Спр.Наименование);

			ИначеЕсли (ФорматПредставления = 2) или (ВРег(ФорматПредставления) = ВРег("ИмяКод")) Тогда

				ДокСтр = "¦" + Строка(Спр.Код);
				ДокСтр = ДокСтр + " " + СокрЛП(Спр.Наименование);

			ИначеЕсли (ФорматПредставления = 3) или (ВРег(ФорматПредставления) = ВРег("Расширенный")) Тогда

				Комментарий = Метаданные.Документ(Спр.Вид()).Комментарий;

				Если ПустоеЗначение(Комментарий) = 0 Тогда
					ДокСтр = Комментарий;
				Иначе
					ДокСтр = ПредставлениеВида;
				КонецЕсли;

				ДокСтр = " ¦" + Строка(Спр.Код);
				ДокСтр = ДокСтр + " " + СокрЛП(Спр.Наименование);

			ИначеЕсли (ФорматПредставления = 4) или (ВРег(ФорматПредставления) = ВРег("ПредставлениеВида")) Тогда

				ДокСтр = ПредставлениеВида;

			Иначе

				Сообщить("Ошибка в функции ПредставлениеСправочника. Неверно указан формат.", "!");

			КонецЕсли;

		Иначе

			ДокСтр = "";

		КонецЕсли;

	Иначе

		Сообщить("Ошибка в функции ПредставлениеСправочника(). Неверный тип значения.", "!");

	КонецЕсли;

	Возврат ДокСтр;

КонецФункции // ПредставлениеСправочника

//******************************************************************************
//	ВклОбъекты(Режим)
//
//	Параметры:
//		РежимПометки - режим установки пометок ("Все", "Сброс", "Инверсия")
//
//	Описание:
//		Помечает, снимает или инвертирует установленные пометки в списке на форме
//
Процедура ВклОбъекты(РежимПометки, СписокНаФорме) Экспорт

	Для Сч = 1 по СписокНаФорме.РазмерСписка() Цикл
		Если РежимПометки = "Все" тогда
			СписокНаФорме.Пометка(Сч,1)
		ИначеЕсли РежимПометки = "Сброс" тогда
			СписокНаФорме.Пометка(Сч,0)
		Иначе
			Если СписокНаФорме.Пометка(Сч) = 1 тогда
				СписокНаФорме.Пометка(Сч,0)
			Иначе
				СписокНаФорме.Пометка(Сч,1)
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;

КонецПроцедуры // ВклОбъекты

//------------------------------------ ------------------------------------
// является ли переданный экземпляр переданным типом или производным от него
Функция ЯвляетсяТипом(ЭкземплярКласса, ИмяКласса) Экспорт
	Если ТипЗначенияСтр(ЭкземплярКласса)=ИмяКласса Тогда
		Возврат 1;
	КонецЕсли;

	Возврат Этот(Контекст).ЯвляетсяПроизводнымОт(ЭкземплярКласса, ИмяКласса);
КонецФункции //ЯвляетсяТипом

//------------------------------------ ------------------------------------
// получить модуль числа
Функция ABS(Параметр) Экспорт
	Если Параметр < 0  Тогда
		Возврат (0 - Параметр);
	КонецЕсли;
	Возврат Параметр;
КонецФункции //ABS

//------------------------------------ ------------------------------------
// имя переменной обязательно должно быть в кавычках
//	void СообщитьОтладка(Строка ИмяПеременной);
Процедура СообщитьОтладка(ИмяПеременной) Экспорт
	Сообщить(ИмяПеременной +" = "+Шаблон("["+ИмяПеременной+"]"));
КонецПроцедуры // СообщитьОтладка

//------------------------------------ ------------------------------------
// выполнить произвольную процедуру или функцию (про функцию ВНИМАТЕЛЬНО смотри НИЖЕ )
// ВНИМАНИЕ: в случае вызова через СервисРасшФормы исключения не обрабатываются (такое поведение у СервисРасшФормы.ВыполнитьПроцедуу(ВыполнитьФункцию)
// А при работе через "ВыполняемыйМодуль" почти все прекрасно,
// кроме того, что, когда фТолькоПроцедура = 0, при вызове процедуры в окне сообщений появляется ошибка компиляции, вызванная преднамеренно
//
Функция _ВыполнитьВКонтексте(Конт, ИмяПроцедуры, СтрПараметрыПроцедуры, фТолькоПроцедура) Экспорт

// -----------------------------------------------
// глюк 1С++ если работать через СервисРасшФормы :
// если ИмяПроцедуры - это на самом деле функция и в при ее выполнении возникает необработнное исключение,
// в этом случае эта функция выполнится ЦЕЛЫХ 2 РАЗА !!
//// 1 вариант
//	//лСервисРасшФормы = СоздатьОбъект("СервисРасшФормы");
//	//лСервисРасшФормы.ВыполнитьПроцедуру(, ИмяПроцедуры);
//	//// или вот так, но ...
//	////Результат = 2986526987;
//	////лСервисРасшФормы.ВыполнитьФункцию(, ИмяПроцедуры,,Результат);
//	////Если Результат = 2986526987 Тогда  // АККУРАТНО
//	////// невозможно отличить 2 ситуации:
//	////// когда ИмяПроцедуры - это процедура,
//	////// или при выполнении функции с таким именем возникло исключение
//	////	лСервисРасшФормы.ВыполнитьПроцедуру(, ИмяПроцедуры);
//	////КонецЕсли;
// -----------------------------------------------

// 2 вариант - более удачный, через "ВыполняемыйМодуль"
	Модуль = СоздатьОбъект("ВыполняемыйМодуль");
	Модуль.НазначитьКонтекст(Конт);
	Модуль.ПрисоединитьТекущийМодуль();

	лСигнатура = 56301780734;
	лТекстМодуляНачало = "
		|Функция Получить() Экспорт
		|Попытка ";

	лТекстВызоваПроцедуры = " "+ИмяПроцедуры+"("+СтрПараметрыПроцедуры+"); Возврат "+Строка(лСигнатура)+";";
	лТекстВызоваФункции = " Результат = "+ИмяПроцедуры+"("+СтрПараметрыПроцедуры+"); Возврат Результат;";

	лТекстМодуляЗавершение = "
		|Исключение
			|Модуль = СоздатьОбъект(""ВыполняемыйМодуль"");
			|лИсключение = Модуль.ПолучитьИсключение();
			|лСписокПараметров = СоздатьОбъект(""СписокЗначений"");
			|лСписокПараметров.Установить(""Сигнатура"","+Строка(лСигнатура)+");
			|лСписокПараметров.Установить(""Исключение"",лИсключение);
			|лСписокПараметров.Установить(""ОписаниеОшибки"",ОписаниеОшибки());
			|Возврат лСписокПараметров;
			//|Возврат 0;
		|КонецПопытки;
		|КонецФункции";

	Если фТолькоПроцедура = 0 Тогда
		лТекстМодуля = лТекстМодуляНачало + лТекстВызоваФункции + лТекстМодуляЗавершение;
		//Сообщить("лТекстМодуля - "+лТекстМодуля);

		Модуль.УстановитьМодуль(лТекстМодуля);

		лфЭтоФункция = 1;
		Результат = Модуль.КомпилироватьМодуль();
		Если Результат = 0 Тогда // Тогда это не функция, а процедура
			лфЭтоФункция = 0;
			Сообщить("Не обращайте внимания на предыдущее сообщение !!");
			лТекстМодуля = лТекстМодуляНачало + лТекстВызоваПроцедуры + лТекстМодуляЗавершение;
			Модуль.УстановитьМодуль(лТекстМодуля);
			Результат = Модуль.КомпилироватьМодуль();
		КонецЕсли;
	Иначе // только процедура (без извратов)
		лфЭтоФункция = 0;
		лТекстМодуля = лТекстМодуляНачало + лТекстВызоваПроцедуры + лТекстМодуляЗавершение;
		Модуль.УстановитьМодуль(лТекстМодуля);
		Результат = Модуль.КомпилироватьМодуль();
	КонецЕсли;
	Результат = Модуль.ВыполнитьМодуль();

	Результат = Модуль.Получить();
	Если лфЭтоФункция = 1 Тогда
		// это результат
		Если ТипЗначенияСтр(Результат) = "СписокЗначений" Тогда // было исключение
			Если Результат.Получить("Сигнатура") = лСигнатура Тогда
				лИсключение = Результат.Получить("Исключение");
				Если ТипЗначения(лИсключение) <> 0 Тогда
					Модуль = СоздатьОбъект("ВыполняемыйМодуль");
					Модуль.ВыброситьИскл(лИсключение);
				Иначе
					Модуль = СоздатьОбъект("ВыполняемыйМодуль");
					Модуль.ВыброситьИскл(, Результат.Получить("ОписаниеОшибки"));
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
		// это результат выполнения вызванной функции
		Возврат Результат;
	Иначе
		Если Результат = лСигнатура Тогда
			// исключения не возникло
			Возврат ПустоеЗначение("Строка");
		ИначеЕсли ТипЗначенияСтр(Результат) = "СписокЗначений" Тогда // было исключение
			//Если Результат.Получить("Сигнатура") = лСигнатура Тогда
			лИсключение = Результат.Получить("Исключение");
			Если ТипЗначения(лИсключение) <> 0 Тогда
				Модуль = СоздатьОбъект("ВыполняемыйМодуль");
				Модуль.ВыброситьИскл(лИсключение);
			Иначе
				Модуль = СоздатьОбъект("ВыполняемыйМодуль");
				Модуль.ВыброситьИскл(, Результат.Получить("ОписаниеОшибки"));
			КонецЕсли;
			//КонецЕсли;
		КонецЕсли;
		// быть того не может
		Модуль = СоздатьОбъект("ВыполняемыйМодуль");
		Модуль.ВыброситьИскл(,"быть того не может!!");
	КонецЕсли;
	//Сообщить("Результат - "+Результат);

КонецФункции // _ВыполнитьВКонтексте

//------------------------------------ ------------------------------------
// выполнить произвольную процедуру или функцию (про функцию ВНИМАТЕЛЬНО смотри НИЖЕ )
// ВНИМАНИЕ: в случае вызова через СервисРасшФормы исключения не обрабатываются (такое поведение у СервисРасшФормы.ВыполнитьПроцедуу(ВыполнитьФункцию)
// А при работе через "ВыполняемыйМодуль" почти все прекрасно,
// кроме того, что при вызове процедуры в окне сообщений появляется ошибка компиляции, вызванная преднамеренно
//
Функция ВыполнитьВКонтексте(Конт, ИмяПроцедуры, СтрПараметрыПроцедуры = "") Экспорт
	_ВыполнитьВКонтексте(Конт, ИмяПроцедуры, СтрПараметрыПроцедуры, 0);
КонецФункции // ВыполнитьВКонтексте

//------------------------------------ ------------------------------------
// выполнить произвольную процедуру
Процедура ВыполнитьПроцедуруВКонтексте(Конт, ИмяПроцедуры, СтрПараметрыПроцедуры = "") Экспорт
	_ВыполнитьВКонтексте(Конт, ИмяПроцедуры, СтрПараметрыПроцедуры, 1);
КонецПроцедуры // ВыполнитьПроцедуруВКонтексте

//------------------------------------ ------------------------------------
// выбросить исключение с показом ошибки
//	void ВыброситьИсключение(Строка ТекстИсключения);
//
Процедура ВыброситьИсключение(ТекстИсключения) Экспорт
	Сообщить("ОШИБКА: "+ТекстИсключения,"!!!");
	лМодуль = СоздатьОбъект("ВыполняемыйМодуль");
	лМодуль.ВыброситьИскл(ТекстИсключения, ТекстИсключения);
КонецПроцедуры // ВыброситьИсключение


//******************************************************************************
// глРазложитьНаПериоды(ДатаНачала,ДатаОкончания)
//
// Параметры:
//    ДатаНачала - начало большого периода
//    ДатаОкончания - окончание большого периода
//
// Возвращаемое значение:
//    Таблица дат, если период верный
//    пустую таблицу, если дата окончания меньше даты начала
//
// Описание:
//    раскладывает один большой период на периоды по месяцам
//    формирует таблицу дат начала и окончания в порядке возрастания,
//    например, период 12.02.2002-19.05.2002 будет преобразован в таблицу:
//      12.02.2002  28.02.2002
//    01.03.2002  31.03.2002
//    01.04.2002  30.04.2002
//    01.05.2002  19.05.2002
Функция РазложитьПериодПоМесячнымИнтервалам(ДатаНачала,ДатаОкончания) Экспорт

  лТаблицаДат = СоздатьОбъект("ТаблицаЗначений");
  Если Дата(ДатаОкончания)<Дата(ДатаНачала) Тогда
    Возврат лТаблицаДат;
  КонецЕсли;

  лТаблицаДат.НоваяКолонка("ДатаНачала","Дата");
  лТаблицаДат.НоваяКолонка("ДатаОкончания","Дата");
  ТекДатаНачала = ДатаНачала;
  ТекДатаОкончания= Мин(КонМесяца(ТекДатаНачала),ДатаОкончания);//весь период может уместиться в один месяц

  Пока ТекДатаОкончания <= ДатаОкончания Цикл
    лТаблицаДат.НоваяСтрока();
    лТаблицаДат.УстановитьЗначение(лТаблицаДат.КоличествоСтрок(),1,ТекДатаНачала);
    лТаблицаДат.УстановитьЗначение(лТаблицаДат.КоличествоСтрок(),2,ТекДатаОкончания);
    //новые значения для след периода:
    ТекДатаНачала = ТекДатаОкончания+1;
    Если ТекДатаНачала>ДатаОкончания Тогда
        Прервать;
    КонецЕсли;
    ТекДатаОкончания= Мин(КонМесяца(ТекДатаНачала),ДатаОкончания);
  КонецЦикла;

  Возврат лТаблицаДат;

КонецФункции  // РазложитьПериодПоМесячнымИнтервалам

function ПроверкаИННФизЛица(INN) Export
  var q12[11];
  var c, i,j,CRC;
  q12[1]=3; q12[2]=7; q12[3]=2; q12[4]=4; q12[5]=10; q12[6]=3; q12[7]=5; q12[8]=9; q12[9]=4; q12[10]=6; q12[11]=8;

  ValidINN=0; INN1=trimAll(INN);
  if INN1="" then return ValidINN endif;
  if StrLen(INN1)=12 then
     c=0;
     for i=1 to 10 do
        j=mid(INN1,i,1);
        if (j<"0") or (j>"9") then
			//Message("В ИНН должны быть цифpы!");
            ValidINN=0; Return ValidINN
		endif;
		j=Number(j);
        c=c+j*q12[i+1]
     enddo;
     CRC=  (c % 11) % 10;

     c=0;
     for i=1 to 10 do
        j=Number(mid(INN1,i,1));
        c=c+j*q12[i]
     enddo;
     c=c+CRC*q12[11];
     CRC= CRC*10+ (c % 11) % 10;
     j=mid(INN1,11,2);
     if (j<"00") or (j>"99") then
	 	//Message("В ИНН должны быть цифpы!");
         ValidINN=0; Return validINN
	 endif;
	 j=Number(j);
     if j<>CRC  then
	 	//Message("Такой ИНН не существует!");
         ValidINN=0; Return validINN
	 endif;
  else
	//Message("В ИНН должны быть ровно 12 цифр!");
         ValidINN=0; Return validINN
  endif
endfunction

// получить имя базы 1С, как оно представлено в окне запуска 1С
Функция ИмяБазы() Экспорт
  Попытка
    scrpt=createobject("scriptcontrol");
    scrpt.language="vbs";
    scrpt.addcode
      (
      "Function Get1CV7BaseName(strPath)
      |const HKEY_CURRENT_USER = &H80000001
      |Set objReg = GetObject(""winmgmts:\root\default:StdRegProv"")
      |strKeyPath = ""Software\1C\1Cv7\7.7\Titles""
      |strValue = vbNullString
      |objReg.GetStringValue HKEY_CURRENT_USER, strKeyPath, strPath, strValue
      |Get1CV7BaseName = strValue
      |End Function"
      );
    Возврат(scrpt.run("Get1CV7BaseName",КаталогИБ()));
  Исключение
    Возврат("");
  КонецПопытки;
КонецФункции //ИмяБазы()

//
//	Функция читает список зарегистрированных информационных баз 1С из реестра Windows
//		и возвращает таблицу значений с колонками "Название" и "Путь":
//
Функция глПолучитьСписокИБ() Экспорт
	ТаблЗнач=СоздатьОбъект("ТаблицаЗначений");
	ТаблЗнач.НоваяКолонка("Название");
	ТаблЗнач.НоваяКолонка("Путь");

	Попытка
		ScrptCtrl=СоздатьОбъект("MSScriptControl.ScriptControl");
		ScrptCtrl.Language="vbscript";
		ScrptCtrl.AddCode("
			|Function Get1CV77Titles()
			|const HKEY_CURRENT_USER = &H80000001
			|Set oReg=GetObject(""winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv"")
			|strKeyPath = ""Software\1C\1Cv7\7.7\Titles""
			|oReg.EnumValues HKEY_CURRENT_USER, strKeyPath, arrValues
			|strInfo=vbNullString
			|For i = LBound(arrValues) To UBound(arrValues)
			|call oReg.GetStringValue(HKEY_CURRENT_USER,strKeyPath,arrValues(i),Value)
			|strInfo=strInfo & arrValues(i) & vbTab & Value & vbCrLf
			|Next
			|Get1CV77Titles = strInfo
			|End Function
			|");
		Текст=СокрЛП(ScrptCtrl.Run("Get1CV77Titles"));
	Исключение
		Сообщить(ОписаниеОшибки());
		Возврат ТаблЗнач;
	КонецПопытки;

	Для ы=1 по СтрКоличествоСтрок(Текст) Цикл
		СтрБазы=СтрПолучитьСтроку(Текст,ы);
		Разд=Найти(СтрБазы,СимволТабуляции);
		Путь=Лев(СтрБазы,Разд-1);
		Название=Прав(СтрБазы,СтрДлина(СтрБазы)-Разд);
		ТаблЗнач.НоваяСтрока();
		ТаблЗнач.Название=Название;
		ТаблЗнач.Путь=Путь;
	КонецЦикла;

	ТаблЗнач.Сортировать("Название");
	Возврат ТаблЗнач;
КонецФункции //глПолучитьСписокИБ

Функция ПолучитьСписокПринтеров() Экспорт
	сзПринтер = СоздатьОбъект("СписокЗначений");
	//Получить список принтеров:
	wshNetwork=createObject("WScript.Network");
	oPrinters=wshNetwork.EnumPrinterConnections();
	i=0;
	while i<oPrinters.count()-1 do
		сзПринтер.ДобавитьЗначение(СокрЛП(oPrinters.item(i+1)));
		i=i+2;
	enddo;

	Возврат сзПринтер;
КонецФункции	// ПолучитьСписокПринтеров

Функция ПринтерПоУмолчанию() Экспорт
	scrptCtrl=createobject("MSScriptControl.ScriptControl");
	scrptCtrl.language="vbscript";

	scrptCtrl.addcode("
		|Function GetDefaultPrinter()
		|GetDefaultPrinter=vbNullString
		|Set objWMIService=GetObject(""winmgmts:"" _
		|& ""{impersonationLevel=impersonate}!\\.\root\cimv2"")
		|Set colInstalledPrinters=objWMIService.ExecQuery _
		|(""Select * from Win32_Printer"")
		|For Each objPrinter in colInstalledPrinters
		|If objPrinter.Attributes and 4 Then
		|GetDefaultPrinter=objPrinter.Name
		|Exit For
		|End If
		|Next
		|End Function");
	//ПринтерПоУмолчанию = scrptCtrl.run("GetDefaultPrinter");

	Возврат scrptCtrl.run("GetDefaultPrinter");

КонецФункции // ПринтерПоУмолчанию

Функция ВыбратьПринтер() Экспорт
	Перем Принтер;

	лСписокПринтеров = Сам(Контекст).ПолучитьСписокПринтеров();

	стр = лСписокПринтеров.НайтиЗначение(СокрЛП(Сам(Контекст).ПринтерПоУмолчанию()));
	Если ПустоеЗначение(стр) = 1 Тогда
	    стр = 1;
	КонецЕсли;
	лСписокПринтеров.ВыбратьЗначение(Принтер, "Принтер", стр, 0, 0);

	Возврат Принтер;
КонецФункции	// ВыбратьПринтер

// усыпить 1С на нужное время
//
// 	Вызов функций из Win32API в скриптах
//		[http://ourworld.compuserve.com/homepages/Guenter_Born/WSHBazaar/dynawrapNt.zip]
//
Процедура Спать(милисек) Экспорт
	UserWrap = CreateObject("DynamicWrapper");
	// first register the API function
	UserWrap.Register("KERNEL32.DLL", "Sleep", "I=l", "f=s", "R=l");

	UserWrap.Sleep(милисек);

КонецПроцедуры // Спать


//------------------------------------ ------------------------------------
// быстрое создание объектов
//
// Но лучше написать подобные функции прямо в модуле, в котором они будут использоваться
// будет быстрее в два/три раза
//
Функция СоздатьСписокЗначений() Экспорт
	Перем Результат;
	_ЗаготовкаСпискаЗначений.Выгрузить(Результат);
	Возврат Результат;
КонецФункции //СоздатьСписокЗначений

Функция СоздатьТаблицуЗначений() Экспорт
	Перем Результат;
	_ЗаготовкаСпискаЗначений.Выгрузить(Результат);
	Возврат Результат;
КонецФункции //СоздатьТаблицуЗначений

// быстрый, но чуть более медленный, чем 1 вариант
Функция СоздатьСписокЗначений2() Экспорт
	Возврат ЗначениеИзСтрокиВнутр(_ЗаготовкаСпискаЗначений2);
КонецФункции //СоздатьСписокЗначений2

// быстрый, но чуть более медленный, чем 1 вариант
Функция СоздатьТаблицуЗначений2() Экспорт
	Возврат ЗначениеИзСтрокиВнутр(_ЗаготовкаТаблицыЗначений2);
КонецФункции //СоздатьТаблицуЗначений2

//******************************************************************************
// глЕстьРеквизитШапки(ИмяРеквизита, ВидДокумента)
//
// Параметры:
//  ИмяРеквизита - имя реквизита (строка)
//  ВидДокумента - вид документа (строка)
//
// Возвращаемое значение:
//  0 - нет реквизита,
//  1 - есть реквизит
//
// Описание:
//  Проверяет, есть ли в структуре метаданных документа указанного вида
// 	реквизит шапки с указанным названием
//
Функция ЕстьРеквизитШапки(ИмяРеквизита, ВидДокумента) Экспорт


	Если ПустоеЗначение(ИмяРеквизита) = 1 Тогда
		Возврат 0;

	ИначеЕсли Метаданные.ОбщийРеквизитДокумента(ИмяРеквизита).Выбран() = 1 Тогда
		Возврат 1;

	ИначеЕсли ПустоеЗначение(ВидДокумента) = 1 Тогда
		Возврат 0;

	ИначеЕсли Метаданные.Документ(ВидДокумента).РеквизитШапки(ИмяРеквизита).Выбран() = 1 Тогда
		Возврат 1;

	Иначе
		Возврат 0;
	КонецЕсли;

КонецФункции //глЕстьРеквизитШапки()

//******************************************************************************
// глЕстьРеквизитМнЧ(ИмяРеквизита, ВидДокумента)
//
// Параметры:
//  ИмяРеквизита - имя реквизита (строка)
//  ВидДокумента - вид документа (строка)
//
// Возвращаемое значение:
//  0 - нет реквизита,
//  1 - есть реквизит
//
// Описание:
//  Проверяет, есть ли в структуре метаданных документа указанного вида
//	реквизит многострочной части с указанным названием
//
Функция ЕстьРеквизитМнЧ(ИмяРеквизита,ВидДокумента) Экспорт
	Перем Реквизит;
	Если (ПустоеЗначение(ВидДокумента) = 1) ИЛИ
	     (ПустоеЗначение(ИмяРеквизита) = 1) Тогда
		Возврат 0;
	КонецЕсли;
	Реквизит=Метаданные.Документ(ВидДокумента).РеквизитТабличнойЧасти(ИмяРеквизита);
	Возврат Реквизит.Выбран();
КонецФункции //глЕстьРеквизитМнЧ()

//_________________________________________________________
//
// Универсальный перевод чисел в разные системы исчисления
// http://www.sinor.ru/~my1c/knowhow/uni_conv.html
//
Функция Из_10_В_Любую(Знач Значение=0,Нотация=36) Экспорт
     Если Нотация<=0 Тогда Возврат("") КонецЕсли;
     Значение=Число(Значение);
     Если Значение<=0 Тогда Возврат("0") КонецЕсли;
     Значение=Цел(Значение);
     Результат="";
     Пока Значение>0 Цикл
          Результат=Сред("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",Значение%Нотация+1,1)+Результат;
          Значение=Цел(Значение/Нотация) ;
     КонецЦикла;
     Возврат Результат;
КонецФункции

//_________________________________________________________
//
// Универсальный перевод чисел в разные системы исчисления
// http://www.sinor.ru/~my1c/knowhow/uni_conv.html
//
Функция Из_Любой_В_10(Знач Значение="0",Нотация=36) Экспорт
     Если Нотация<=0 Тогда Возврат(0) КонецЕсли;
     Значение=СокрЛП(Значение);
     Если Значение="0" Тогда Возврат(0) КонецЕсли;
     Результат=0;
     Длина=СтрДлина(Значение);
     Для Х=1 По Длина Цикл
          М=1;
          Для У=1 По Длина-Х Цикл М=М*Нотация КонецЦикла;
          Результат=Результат+(Найти("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",Сред(Значение,Х,1))-1)*М;
     КонецЦикла;
     Возврат Окр(Результат);
КонецФункции
