Добавил в условие обычный принт:
else { Print ("_LastError ", _LastError); }
На выходе тоже самое... Т.е. всё дело в самом возврате _LastError, а не в моей функции логирования. Вот что вижу:
2015.07.21 22:19:14.755 ZZBaseVariant USDJPY,H1: _LastError 0 2015.07.21 22:19:14.755 ZZBaseVariant USDJPY,H1: _LastError 0 2015.07.21 22:19:14.755 ZZBaseVariant USDJPY,H1: _LastError 0 2015.07.21 22:19:14.755 ZZBaseVariant USDJPY,H1: _LastError 0 2015.07.21 22:19:14.755 ZZBaseVariant USDJPY,H1: _LastError 0
Значение _LastError изменяется после вызова каждой последующей функции. В приведенном коде код ошибки изменен после вызова StringSubstr.
Чтобы получить код ошибки, возникшей после вызова определенной функции, нужно кэшировать этот код сразу же после вызова такой функции. К примеру, если нужно получить код ошибки после выполнения ObjectName, то лучше сделать так:
objName = ObjectName (obj); int error = GetLastError(); // или _LastError if (StringSubstr (objName, 11, 12) == "OBJ_ARROW_UP") { ObjectDelete (objName); // Перерисуем объект WindowRedraw(); } else { Logging::WriteLog (StringConcatenate (__FUNCTION__, ": Не удалось стереть объект с именем ", objName, ". Ошибка: ", IntegerToString(error)), Logging::NeedLogs, Logging::PrintUP, Logging::CommentUP); }
Что-то не помогло. Вот функция:
// Удаление всех объектов по имени. ======================================================================================================= void DrawGrafics::DeleteAllObjects (void) { string objName = NULL; for (int obj = ObjectsTotal() - 1; obj >= 0; obj--) { objName = ObjectName (obj); int err = GetLastError(); if (StringSubstr (objName, 11, 10) == "BJ_BUTTON") { ObjectDelete (objName); // Перерисуем объект WindowRedraw(); } else { Print ("err: " ,err); Logging::WriteLog (StringConcatenate (__FUNCTION__, " => Не удалось стереть объект с именем: ", objName, ". Ошибка № ", err), Logging::NeedLogs, Logging::PrintUP, Logging::CommentUP); } } }
В журнале:
2015.07.22 00:13:32.770 ZZBaseVariant USDJPY,H1: DrawGrafics::DeleteAllObjects => Не удалось снести объект с именем USDJPY_H1 _OBJ_BUTTON_0. Ошибка: 0 2015.07.22 00:13:32.769 ZZBaseVariant USDJPY,H1: err: 0 2015.07.22 00:13:32.769 ZZBaseVariant USDJPY,H1: DrawGrafics::DeleteAllObjects => Не удалось снести объект с именем USDJPY_H1 _OBJ_BUTTON_1. Ошибка: 0 2015.07.22 00:13:32.768 ZZBaseVariant USDJPY,H1: err: 0 2015.07.22 00:13:32.768 ZZBaseVariant USDJPY,H1: DrawGrafics::DeleteAllObjects => Не удалось снести объект с именем USDJPY_H1 _OBJ_BUTTON_2. Ошибка: 0 2015.07.22 00:13:32.767 ZZBaseVariant USDJPY,H1: err: 0 2015.07.22 00:13:32.767 ZZBaseVariant USDJPY,H1: DrawGrafics::DeleteAllObjects => Не удалось снести объект с именем USDJPY_H1 _OBJ_BUTTON_3. Ошибка: 0 2015.07.22 00:13:32.766 ZZBaseVariant USDJPY,H1: err: 0 2015.07.22 00:13:32.766 ZZBaseVariant USDJPY,H1: DrawGrafics::DeleteAllObjects => Не удалось снести объект с именем USDJPY_H1 _OBJ_BUTTON_4. Ошибка: 0 2015.07.22 00:13:32.765 ZZBaseVariant USDJPY,H1: err: 0
Что-то не помогло. Вот функция:
В журнале:
У вас вывод сообщения об ошибке за пределами заданного условия для удаления и, соответственно, самого удаления объектов.
Поскольку есть возможность воспользоваться тем, что ObjectDelete имеет тип bool, попробуйте так:
if(StringSubstr(objName,11,10)=="BJ_BUTTON") { ResetLastError(); if(!ObjectDelete(chart_ID,objName)) { Logging::WriteLog(StringConcatenate(__FUNCTION__," => Не удалось стереть объект с именем: ",objName,". Ошибка № ",GetLastError()), Logging::NeedLogs,Logging::PrintUP,Logging::CommentUP); } ChartRedraw(); }P./S.: Параметр chart_ID - из второго варианта ObjectDelete.
А этот блок в вашем коде тогда не потребуется:
else { Print ("err: " ,err); Logging::WriteLog (StringConcatenate (__FUNCTION__, " => Не удалось стереть объект с именем: ", objName, ". Ошибка № ", err), Logging::NeedLogs, Logging::PrintUP, Logging::CommentUP); }
(если, конечно, не будете его применять для прописки каких-либо других свои условий/вывода сообщений).
Написал класс для работы с графикой. Всё, в принципе, отлично. Но есть момент. Спецом допустил ошибку в функции, чтоб проверить что она вернёт за ошибку. В итоге ошибки нет.. Вот метод:
В журнале вижу такое:
Лог не от этого кода.
В коде:
Logging::WriteLog (StringConcatenate (__FUNCTION__, " => Не удалось стереть объект с именем: ", objName, ". Ошибка № ", err),Logging::NeedLogs, Logging::PrintUP, Logging::CommentUP);
Видим в логе:
2015.07.22 00:13:32.770 ZZBaseVariant USDJPY,H1: DrawGrafics::DeleteAllObjects => Не удалось снести объект с именем USDJPY_H1 _OBJ_BUTTON_0. Ошибка: 0
Лог не от этого кода.
В коде:
Видим в логе:
2015.07.22 00:13:32.770 ZZBaseVariant USDJPY,H1: DrawGrafics::DeleteAllObjects => Не удалось снести объект с именем USDJPY_H1 _OBJ_BUTTON_0. Ошибка: 0
Это вы верно подметили.
Однако, на всякий случай всё-таки скажу, что в этом сравнении у него:
if (StringSubstr (objName, 11, 10) == "BJ_BUTTON")
задаётся условие, при котором будет удалён объект и, если оно совпадает, то объект удаляется в блоке кода этого сравнения.
А вывод сообщения об ошибке при удалении объекта, у него в другом блоке. В else условия выше. То бишь, тогда, когда нет удаления объекта. Поэтому и ошибка равна 0.
Кроме того, вместо:
if (StringSubstr (objName, 11, 10) == "BJ_BUTTON")
с моей точки зрения, вот такую замену можно ещё произвести:
string name=StringSubstr(objName,11,10); if(StringCompare(name,"BJ_BUTTON",true)==0) { ...P./S.: Это не в связи с вопросом темы. Это просто дополнение из-за того, что как-то мне не нравится, что в if идёт вызов StringSubstr.
Однако, на всякий случай всё-таки скажу, что в этом сравнении у него:
задаётся условие, при котором будет удалён объект и, если оно совпадает, то объект удаляется в блоке кода этого сравнения.
А вывод сообщения об ошибке при удалении объекта, у него в другом блоке. В else условия выше. То бишь, тогда, когда нет удаления объекта. Поэтому и ошибка равна 0.
Согласен, условие вышло какое-то не продуманное и нелогичное. Теперь понял в чём косяк. Ошибка то получается в другом контексте...
P./S.: Это не в связи с вопросом темы. Это просто дополнение из-за того, что как-то мне не нравится, что в if идёт вызов StringSubstr.
Ну а как тогда быть? Ещё не всё прооптимизировал и не всё дореализовал т.к. там будет под любой объект использоваться. Но суть не в том. А мы о том, что не нравится условие такое... в if имеется вызов StringSubstr. Как тут иначе? Ведь суть в том, что происходит проверка того что объект всё-таки выбран. Иначе дальше не резон двигаться. Поэтому, лично я не наблюдаю вариантов.
Какие будут соображения на этот счёт?
На данный момент, реализация вот такая:
void DrawGrafics::DeleteAllObjects (void) { string objName = NULL; for (int obj = ObjectsTotal(); obj >= 0; obj--) { objName = ObjectName (obj); if (StringSubstr (objName, 11, 10) != "BJ_BUTTON") { ResetLastError(); if (!ObjectDelete (objName)) { Logging::WriteLog (StringConcatenate (__FUNCTION__, " => Не удалось стереть объект с именем: ", objName, ". Ошибка № ", _LastError), Logging::NeedLogs, Logging::PrintUP, Logging::CommentUP); } // Перерисуем объект WindowRedraw(); } } }
Ну а как тогда быть? Ещё не всё прооптимизировал и не всё дореализовал т.к. там будет под любой объект использоваться. Но суть не в том. А мы о том, что не нравится условие такое... в if имеется вызов StringSubstr. Как тут иначе? Ведь суть в том, что происходит проверка того что объект всё-таки выбран. Иначе дальше не резон двигаться. Поэтому, лично я не наблюдаю вариантов.
Какие будут соображения на этот счёт?
На данный момент, реализация вот такая:
Так я вам и предложила здесь пооптимальнее условия проверки. ) В том числе, исходя из костяка схемы кода и предполагая, что в дальнейшем он будет видоизменяться и/или дополняться. Эти функции - и есть под любой объект и разнообразные условия (в контексте вашего кода). Включая, когда будут заменены переменными эти значения: 10, 11, "BJ_BUTTON" и true, при необходимости.
В том числе, StringCompare - всё-таки поуниверсальнее в дальнейшем применении, чем (образно) просто: if (x=="abc"). Плюс, эта функция специально предназначена для сравнений строк.
Вывод её результата сравнения в виде числа может пригодиться и при постановке определённых условий (то есть, снова образный пример: если 0, удаляем объект; если -1, то делаем то; если 1, то другое).
/*И эту функцию, в принципе, можно из условий сравнения сначала в переменную вывести, а затем уже переменную - в if или switch, где дальнейшие условия будут определяться на основе значений этой переменной.*/
P./S.: А не нравится StringSubstr в if, поскольку итак строковые данные обрабатываются дольше всего. Да и обработка функций в самом условии условного оператора if, подольше вроде как.
Поэтому вызов этой функции до условного оператора, а не в его условии, с моей точки зрения, всё-таки пооптимальнее будет.
Как-то так.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Написал класс для работы с графикой. Всё, в принципе, отлично. Но есть момент. Спецом допустил ошибку в функции, чтоб проверить что она вернёт за ошибку. В итоге ошибки нет.. Вот метод:
В журнале вижу такое: