Переключение на Главную Страницу Страницы: 1 2 [3] 4  ОтправитьПечать
Очень популярная тема (более 25 ответов) Как найти причину вылета 1С++? (число прочтений - 14962 )
es3000
God Member
*****
Отсутствует



Сообщений: 536
Зарегистрирован: 10. Июля 2006
Re: Как найти причину вылета 1С++?
Ответ #30 - 28. Ноября 2012 :: 09:44
Печать  
Eprst писал(а) 28. Ноября 2012 :: 09:15:
переустанови vfp

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

Eprst писал(а) 28. Ноября 2012 :: 09:15:
если запрос правильно построен с учетом использования индексов, то sqllite ему проигрывает в разы на некоторых запросах (особенно, где group by есть)

да бог с ней с производительностью...
главное чтоб работало.
  
Наверх
ICQ  
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Как найти причину вылета 1С++?
Ответ #31 - 29. Ноября 2012 :: 06:42
Печать  
es3000 писал(а) 28. Ноября 2012 :: 08:36:
Выяснилось: ИТ не при чем, ИТ отрабатывает нормально,
вылеты происходят когда выполняется:
КомандаОЛЕ.УложитьСписокОбъектов(лСписокНом, ВремТабл);


ну так и реализуй свою функцию создания фильтрующей времТЗ (или создание условия вида In(, , , , ...) при малых количествах фильтрующих значений).
  
Наверх
 
IP записан
 
es3000
God Member
*****
Отсутствует



Сообщений: 536
Зарегистрирован: 10. Июля 2006
Re: Как найти причину вылета 1С++?
Ответ #32 - 29. Ноября 2012 :: 08:02
Печать  
Satans Claws писал(а) 29. Ноября 2012 :: 06:42:
ну так и реализуй свою функцию создания фильтрующей времТЗ (или создание условия вида In(, , , , ...) при малых количествах фильтрующих значений).

не понял что значит "реализуй свою функцию создания фильтрующей времТЗ"?
как ее реализовать?
  
Наверх
ICQ  
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Как найти причину вылета 1С++?
Ответ #33 - 30. Ноября 2012 :: 05:30
Печать  
своим инсёртом во временную табличку..
вот только группы разворачивать придётся до полной иерархии.
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Как найти причину вылета 1С++?
Ответ #34 - 30. Ноября 2012 :: 10:11
Печать  
Eprst писал(а) 30. Ноября 2012 :: 05:30:
своим инсёртом во временную табличку..
вот только группы разворачивать придётся до полной иерархии.


Функция пишется за 15 минут.
Если угореть по хардкору и прикрутить на справочник тригер, который будет в отдельной табличке писать иерархию - то там вообще все становится сочне-сочне.
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Как найти причину вылета 1С++?
Ответ #35 - 30. Ноября 2012 :: 10:18
Печать  
Вот кусок из функции, написанной 2 года назад, когда я "с нуля" писал набор классов на новой (в тот момент) работе


Код
Выбрать все
	ИначеЕсли ТипЗначения(ЗначениеФильтра) = 11 Тогда
		Если ЗначениеФильтра.ЭтоГруппа() = 0 Тогда
			Если фДекларативныеФильтры = 0 Тогда
				стрЗначение = "'" + РадугаСервис.ЗначениеВСтрокуБД(ЗначениеФильтра) + "'";
			Иначе
				текст_Декларация = текст_Декларация + "
				|Declare " + стрЗначение + " Char(9)
				|Set " + стрЗначение + " = '" + РадугаСервис.ЗначениеВСтрокуБД(ЗначениеФильтра) + "'";
			КонецЕсли;
		Иначе
			ИмяВремТаблицы	= ИмяВременнойТаблицы(, 0);

			ТекстЗапроса = "
			|SELECT '" + РадугаСервис.ЗначениеВСтрокуБД(ЗначениеФильтра) + "' ID Into " + ИмяВремТаблицы + "
			|
			|While @@RowCount > 0
			|INSERT INTO " + ИмяВремТаблицы + "
			|SELECT
			|	Спр.ID
			|FROM
			|	$Справочник." + ЗначениеФильтра.Вид() + " Спр (NoLock)
			|WHERE
			|	ParentID In (SELECT ID FROM " + ИмяВремТаблицы + " (NoLock))
			|	And ID Not In (SELECT ID FROM " + ИмяВремТаблицы + " (NoLock))
			|
			|If (SELECT Count(*) From " + ИмяВремТаблицы + " (NoLock)) > 100
			|	Create Clustered Index " + СтрЗаменить(ИмяВремТаблицы, "[#", "[#IX_") + " on " + ИмяВремТаблицы + " (ID)
			|";

			Если фЗаполняемВремТаблицыОтдельнымЗапросом = 1 Тогда
				ЗапросСКЛ.Выполнить("Set NoCount ON
				|" + ТекстЗапроса);
			Иначе
				текст_Префикс = текст_Префикс + ТекстЗапроса;
			КонецЕсли;

			текст_Постфикс = текст_Постфикс + "
			|Drop Table " + ИмяВремТаблицы;
		КонецЕсли;

	ИначеЕсли ТипЗначенияСтр(ЗначениеФильтра) = "СписокЗначений" Тогда
		фИспользоватьВТ = 0;
		Если ЗначениеФильтра.РазмерСписка() > 10 Тогда
			фИспользоватьВТ = 1;
		Иначе
			Для й = 1 По ЗначениеФильтра.РазмерСписка() Цикл
				ОдноИзЗначений = ЗначениеФильтра.ПолучитьЗначение(й);
				Если ТипЗначения(ОдноИзЗначений) = 11 Тогда
					Если ОдноИзЗначений.ЭтоГруппа() = 1 Тогда
						фИспользоватьВТ = 1;
						Прервать;
					КонецЕсли;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;

		Если фИспользоватьВТ = 0 Тогда
			Для й = 1 По ЗначениеФильтра.РазмерСписка() Цикл
				ОдноИзЗначений = ЗначениеФильтра.ПолучитьЗначение(й);
				Если ПустоеЗначение(ОдноИзЗначений) = 1 Тогда
					Продолжить;
				КонецЕсли;
				СписокЗначений = СписокЗначений + ", '" + РадугаСервис.ЗначениеВСтрокуБД(ОдноИзЗначений) + "'";
			КонецЦикла;

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

			ТекстЗапроса = "
			|CREATE TABLE " + ИмяВремТаблицы + " (ID Char(9))";

			фЭтоСправочник = 0;
			Для й = 1 По ЗначениеФильтра.РазмерСписка() Цикл
				ОдноИзЗначений = ЗначениеФильтра.ПолучитьЗначение(й);
				Если ПустоеЗначение(ОдноИзЗначений) = 1 Тогда
					Продолжить;
				КонецЕсли;
				ТекстЗапроса = ТекстЗапроса + "
				|INSERT INTO " + ИмяВремТаблицы + " Values('" + РадугаСервис.ЗначениеВСтрокуБД(ОдноИзЗначений) + "')";

				Если ТипЗначения(ОдноИзЗначений) = 11 Тогда
					фЭтоСправочник = 1;
					ВидСпр = ОдноИзЗначений.Вид();
				КонецЕсли;
			КонецЦикла;

			Если фЭтоСправочник = 1 Тогда
				МетаСпр = Метаданные.Справочник(ВидСпр);
				Если МетаСпр.КоличествоУровней > 1 Тогда
					ТекстЗапроса = ТекстЗапроса + "
					|
					|While @@RowCount > 0
					|INSERT INTO " + ИмяВремТаблицы + "
					|SELECT
					|	Спр.ID
					|FROM
					|	$Справочник." + ВидСпр + " Спр (NoLock)
					|WHERE
					|	ParentID In (SELECT ID FROM " + ИмяВремТаблицы + " (NoLock))
					|	And ID Not In (SELECT ID FROM " + ИмяВремТаблицы + " (NoLock))
					|";
				КонецЕсли;
			КонецЕсли;

			ТекстЗапроса = ТекстЗапроса + "
			|If (SELECT Count(*) From " + ИмяВремТаблицы + " (NoLock)) > 100
			|	Create Clustered Index " + СтрЗаменить(ИмяВремТаблицы, "[#", "[#IX_") + " on " + ИмяВремТаблицы + " (ID)
			|";

			Если фЗаполняемВремТаблицыОтдельнымЗапросом = 1 Тогда
				ЗапросСКЛ.Выполнить("Set NoCount ON
				|" + ТекстЗапроса);
			Иначе
				текст_Префикс = текст_Префикс + ТекстЗапроса;
			КонецЕсли;

			текст_Постфикс = текст_Постфикс + "
			|Drop Table " + ИмяВремТаблицы;
		КонецЕсли;
 



Это функция класса ТОтчет.Запрос, отвечающая за построение фильтра по переданному значению.
Есть еще вторая функция, которая готовит фильтр char(13) - она немного сложнее, но принципиально ничем не отличается.

Таблицы деревьев появились относительно недавно, переписать под них фильтры - как-то пока даже надобности не возникало. Устраивает и то, как они сейчас работают.
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Как найти причину вылета 1С++?
Ответ #36 - 30. Ноября 2012 :: 10:21
Печать  
Всё это хорошо, но у автора вроде как дбф.
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Как найти причину вылета 1С++?
Ответ #37 - 03. Декабря 2012 :: 02:37
Печать  
С ДБФом прямыми запросами не приходилось, да.
Там нет возможности покрутить цикл прямо на драйвере?
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Как найти причину вылета 1С++?
Ответ #38 - 03. Декабря 2012 :: 07:53
Печать  
Eprst писал(а) 30. Ноября 2012 :: 10:21:
Всё это хорошо, но у автора вроде как дбф.

похожий  код и ДБФ через FoxPro
вместо
Код
Выбрать все
|Declare " + стрЗначение + " Char(9)
|Set " + стрЗначение + " = '" + РадугаСервис.ЗначениеВСтрокуБД(ЗначениеФильтра) + "'"; 


Код
Выбрать все
PUBLIC " + стрЗначение + "
STORE  '" + РадугаСервис.ЗначениеВСтрокуБД(ЗначениеФильтра) + "'" TO  " + стрЗначение + ""  


вместо
Код
Выбрать все
CREATE TABLE " + ИмяВремТаблицы + " (ID Char(9)) 


Код
Выбрать все
CREATECURSOR  " + ИмяВремТаблицы + "(ID Character(9) NOT NULL) ') 



ну так как выполняеься программа , а не запрос  в конце
Код
Выбрать все
ОлеДБКоманда.Выполнить("EXEC('+ТекстЗапроса+"" ')"); 


подробнее
http://www.1cpp.ru/forum/YaBB.pl?num=1188673318
синтаксис языка
http://www.foxclub.ru/rhproject/project/
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Как найти причину вылета 1С++?
Ответ #39 - 03. Декабря 2012 :: 08:01
Печать  
Да это всё равно ему не нужно..
имхо
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Как найти причину вылета 1С++?
Ответ #40 - 03. Декабря 2012 :: 08:09
Печать  
Никогда не использовал УложитьСписокОбъектов, на живой базе всегда делал вставку во временную таблицу,
правда код был другой? ,больше похожий на
http://www.1cpp.ru/forum/YaBB.pl?num=1188673318#11
никаких вылетов
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Как найти причину вылета 1С++?
Ответ #41 - 03. Декабря 2012 :: 08:12
Печать  
kiruha писал(а) 03. Декабря 2012 :: 08:09:
Никогда не использовал УложитьСписокОбъектов, на живой базе всегда делал вставку во временную таблицу,
правда код был другой? ,больше похожий на
http://www.1cpp.ru/forum/YaBB.pl?num=1188673318#11
никаких вылетов


Ну дык.. не универсально как-то... особенно, через кучу лефт джоинов
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Как найти причину вылета 1С++?
Ответ #42 - 03. Декабря 2012 :: 08:30
Печать  
Универсальность добавить не проблема - вместо 5 уровней - количество уровней в справочнике,
определить через метаданные

Для красоты можно переписать то что для SQL выше написали - если не лень
  
Наверх
 
IP записан
 
Eprst
God Member
*****
Отсутствует



Сообщений: 3397
Зарегистрирован: 08. Октября 2007
Re: Как найти причину вылета 1С++?
Ответ #43 - 03. Декабря 2012 :: 08:38
Печать  
Чорт , я слишком ленивый для этого Улыбка , да и.. по 20000 элементов в список не укладываю, так что и с уложитьсписокОбъектов проблем и вылетов (и тормозов) замечено не было.
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Как найти причину вылета 1С++?
Ответ #44 - 03. Декабря 2012 :: 09:01
Печать  
Eprst писал(а) 03. Декабря 2012 :: 08:38:
по 20000 элементов в список не укладываю, так что и с уложитьсписокОбъектов проблем и вылетов (и тормозов) замечено не было.


если такое большое количество, в Fox строки больше 255 символов не поддерживаются, поэтому надо добавлять
через каждые 10 вставляемых элементов "+CHR(13)+" - символ переноса строки
ну и вставку делать элементов по 100 в цикле - так как на длину запроса тоже есть какое то ограничение
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1 2 [3] 4 
ОтправитьПечать