Как передать параметры в функцию Mql? - страница 2

 
Artyom Trishkin:

Что, какие поля должен содержать ваш объект?

Объект должен быть унаследован от CObject.

Вы должны иметь несколько объектов, унаследованных от CObject. Каждый объект может содержать любое количество нужных ему полей. И, если все они наследуют свойства CObject, то только тогда их можно все собрать в одном CArrayObj.

Я просто не понимаю, и не знаю вообще, что именно должен хранить каждый из ваших объектов.

Распишите их. Тогда можно придумать нормальную компоновку их массива. Вполне может оказаться, что достаточно иметь один объект с множеством полей, подходящих для разных случаев, а может стоит создать множество объектов CObject, каждый из которых будет применим для своего случая, и различать их можно будет по их типу, который будет им каждому вами присвоен.

На данный момент, если брать сигнатуры (имя ведь нам не важно для этого) будет вот так:

{int, string, int, int, double, double, double}
 
Viktar Dzemikhau:

На данный момент, если брать сигнатуры (имя ведь нам не важно для этого) будет вот так:

Вам нужно просто передать в функцию параметром такое именно количество переменных с такими именно типами?

Ну так создайте структуру, имеющую все эти типы. Далее делаете обычный массив такой структуры и передаёте его в функцию.

Простейший пример такой структуры с массивом этих структур array_data[]:

//+------------------------------------------------------------------+
struct SData
  {
   double   double_value_1;
   double   double_value_2;
   double   double_value_3;
   int      integer_value_1;
   int      integer_value_2;
   int      integer_value_3;
   string   string_value_1;
  } array_data[];
//+------------------------------------------------------------------+
 
Artyom Trishkin:

Вам нужно просто передать в функцию параметром такое именно количество переменных с такими именно типами?

Ну так создайте структуру, имеющую все эти типы. Далее делаете обычный массив такой структуры и передаёте его в функцию.

Не то что бы просто. Вот заготовка функции вставки строки в таблицу под СУБД SQLite3:

//==================================================================================================================================================================================
// Insert new row at the end of the table. =========================================================================================================================================
void SQLite3 :: insertRow(string tableName, string& columnNames[]) {
//---
  string sql = "INSERT INTO '" + tableName + "' " +
               "VALUES (?, ?, ?, ?, ?, ?, ?)";

  if (isComplete(sql) != SQLITE_OK) {
    Print(__FUNCTION__ + "Statement isn't complete. Error = ", getErrorMsg());
    return;
  }
  intptr_t stmtHandle;
  if (sqlite3_prepare(m_dbHandle, sql, stmtHandle) != SQLITE_OK) {
    Print(__FUNCTION__ + "Statement isn't prepared. Error = ", getErrorMsg());
    return;
  }
  
  uchar instr[1];
  StringToCharArray("GBRJPY", instr, 0, WHOLE_ARRAY, CP_UTF8);

//  sqlite3_bind_int(stmtHandle, 1, 5);
  sqlite3_bind_text(stmtHandle, 2, instr, -1, SQLITE_TRANSIENT);
  sqlite3_bind_int(stmtHandle, 3, 240);
  sqlite3_bind_int(stmtHandle, 4, 2);
  sqlite3_bind_double(stmtHandle, 5, 11.30);
  sqlite3_bind_double(stmtHandle, 6, 1.28236);
  sqlite3_bind_double(stmtHandle, 7, 0.3);

  if (step(stmtHandle) != SQLITE_DONE) {
    Print(__FUNCTION__ + "Executing statement was failed. Error = ", getErrorMsg());
    return;
  }
  sqlite3_finalize(stmtHandle);
}

По факту, нужно внутри функции insertRow() знать тип соответствующего передаваемого аргумента т.к. это нужно для функций sqlite3_bind_*, которая служит для связки передаваемых аргументов и параметров запроса sql, который подготовлен и скомпилирован уже в функции sqlite3_prepare().

Таким образом, если мы передадим эти аргументы в функцию insertRow() структурой, у нас не будет данных о типах передаваемых аргументов, ведь, опять-таки рефлексии в Mql4(5) нет..

 
Viktar Dzemikhau:

Не то что бы просто. Вот заготовка функции вставки строки в таблицу под СУБД SQLite3:

По факту, нужно внутри функции insertRow() знать тип соответствующего передаваемого аргумента т.к. это нужно для функций sqlite3_bind_*, которая служит для связки передаваемых аргументов и параметров запроса sql, который подготовлен и скомпилирован уже в функции sqlite3_prepare().

Таким образом, если мы передадим эти аргументы в функцию insertRow() структурой, у нас не будет данных о типах передаваемых аргументов, ведь, опять-таки рефлексии в Mql4(5) нет..

Вы вот этим параметром пытаетесь передать нужные данные?

void SQLite3 :: insertRow(string tableName, string& columnNames[])

Откуда хотите брать вот эти данные?

sqlite3_bind_text(stmtHandle, 2, instr, -1, SQLITE_TRANSIENT);
sqlite3_bind_int(stmtHandle, 3, 240);
sqlite3_bind_int(stmtHandle, 4, 2);
sqlite3_bind_double(stmtHandle, 5, 11.30);
sqlite3_bind_double(stmtHandle, 6, 1.28236);
sqlite3_bind_double(stmtHandle, 7, 0.3);

Почему в строковой их 4, а в остальных 2 ?

 
Artyom Trishkin:

Вы вот этим параметром пытаетесь передать нужные данные?

Откуда хотите брать вот эти данные?

Почему в строковой их 4, а в остальных 2 ?

В строковой, как я понял из документации последний параметр т.е. SQLITE_TRANSIENT это деструктор для char* в С++. В общем-то, чаще всего можно сделать как я, и оно так работает. Слишком влазить в дебри нет желания. Тем более, я проверил и всё чётко так у меня пишется. -1 так и останется. Не обращайте внимания на эту цифру.

Второй параметр везде, это порядковый номер параметра для связывания. Он мог бы соответствовать номеру передаваемого массива + 2 т.к. там смещение есть по понятным причинам (если бы я писал Java). Таким образом остаётся передаваемое значение и функция sqlite3_bind_*, которой будем пользоваться.

 
Viktar Dzemikhau:

В строковой, как я понял из документации последний параметр т.е. SQLITE_TRANSIENT это деструктор для char* в С++. В общем-то, чаще всего можно сделать как я, и оно так работает. Слишком влазить в дебри нет желания. Тем более, я проверил и всё чётко так у меня пишется. -1 так и останется. Не обращайте внимания на эту цифру.

Второй параметр везде, это порядковый номер параметра для связывания. Он мог бы соответствовать номеру передаваемого массива + 2 т.к. там смещение есть по понятным причинам (если бы я писал Java). Таким образом остаётся передаваемое значение и функция sqlite3_bind_*, которой будем пользоваться.

Так... Зайдём с другой стороны. Какие именно параметры нужно передать, а какие - лишь ваши придумки для изобретения костыля?

 

Я так понимаю, что нужна автоматизация/связка

string sql = "INSERT INTO '" + tableName + "' " +
               "VALUES (?, ?, ?, ?, ?, ?, ?)";
**********
sqlite3_bind_text(stmtHandle, 2, instr, -1, SQLITE_TRANSIENT);
sqlite3_bind_int(stmtHandle, 3, 240);
sqlite3_bind_int(stmtHandle, 4, 2);
sqlite3_bind_double(stmtHandle, 5, 11.30);
sqlite3_bind_double(stmtHandle, 6, 1.28236);
sqlite3_bind_double(stmtHandle, 7, 0.3);

То есть, при разном количестве и типах элементов, создавать нужную таблицу?

 
Artyom Trishkin:

Так... Зайдём с другой стороны. Какие именно параметры нужно передать, а какие - лишь ваши придумки для изобретения костыля?

Я же написал. В рабочем проекте данные вот такие, если смотреть со стороны SQL:

string columnNames[] = {"'ID' INTEGER PRIMARY KEY AUTOINCREMENT", "'symbolName' TEXT", "'tf' INTEGER", "'orderType' INTEGER", "'openTime' REAL", "'putPrice' REAL", "'unrealizedLot' REAL"};

В Mql это будет вот так:

(string, int, int, long, long, long);

Это типы передаваемых переменных. Так вот нужно передать значения этих переменных и их типы. Если бы была возможность использовать рефлексию, это решалось бы 3 разными случаями, а тут как-бы я не придумал чегонить адекватного. Громоздко получается как-то всё и не универсально. Не буду же я под каждую таблицу писать отдельный метод.. абсурд..

 
Vitaly Muzichenko:

Я так понимаю, что нужна автоматизация/связка

То есть, при разном количестве и типах элементов, создавать нужную таблицу?

Здесь идёт речь не о создании таблицы, а о вставке строки в неё. Обратите внимание на название функции insertRow() и на её описание. У меня в этом всегда порядок. Привык писать чисто, что бы потом было приятно заглянуть код, а не догадываться что я писал когда-то..

Возможность создания я уже реализовал. Там оказалось проще.. Ведь если задуматься, при создании мы передаём лишь названия столбцов т.е. кортежей, а их тип всегда string. Поэтому там я справился обычным массивом типа string. Здесь такой вариант не подходит как видно.. А я уже продолбался не мало времени. Бот уже заждался у утробе лежать.. вылупиться хочет и поторговать))

 
Viktar Dzemikhau:

Здесь идёт речь не о создании таблицы, а о вставке строки в неё. Обратите внимание на название функции insertRow() и на её описание. У меня в этом всегда порядок. Привык писать чисто, что бы потом было приятно заглянуть код, а не догадываться что я писал когда-то..

Возможность создания я уже реализовал. Там оказалось проще.. Ведь если задуматься, при создании мы передаём лишь названия столбцов т.е. кортежей, а их тип всегда string. Поэтому там я справился обычным массивом типа string. Здесь такой вариант не подходит как видно.. А я уже продолбался не мало времени. Бот уже заждался у утробе лежать.. вылупиться хочет и поторговать))

Поможет?
Документация по MQL5: Основы языка / Типы данных / Пользовательские типы
Документация по MQL5: Основы языка / Типы данных / Пользовательские типы
  • www.mql5.com
//|                                                Panel_Buttons.mq5 | //|                        Copyright 2017, MetaQuotes Software Corp. | //|                                             https://www.mql5.com | //| defines                                                          |  INDENT_LEFT                         (11)      ...