bool[] multiInOper = { false, true, false, true, false, false, false, false, false, false, true, false, true, true, false }; //флаг поддержки оператором входов более 2-х //метод загрузки словаря из БД public void LoadDictionary(string BaseAddr) { List <WordsOfDictionary> DictionaryList = new List <WordsOfDictionary>(); DictionaryList.Add(Marka); DictionaryList.Add(TypeFB); DictionaryList.Add(TypeFunc); DictionaryList.Add(TIOCH); ConnectToDB connect = new ConnectToDB(); //в цикле для каждого словаря делаем запрос и заполняем его foreach (WordsOfDictionary Dictionary in DictionaryList) { connect.ConnectToBase(Dictionary.SQL, BaseAddr); TmpDG = connect.dt1; for (int i = 0; i < TmpDG.Rows.Count; i++) { Dictionary.ResultList.Add(TmpDG.Rows[i][0].ToString()); } TmpDG.Clear(); } //добавление словаря операторов почти вручную for (int i = 0; i < nameOper.Length; i++) { Operators op = new Operators(); op.OperName = nameOper[i]; op.OperLevel = levelOper[i]; op.OperID = i; op.OperMultiIn = multiInOper[i]; Oper.Add(op); } /* * Oper.ResultList.Add("-"); * Oper.ResultList.Add("*"); * Oper.ResultList.Add("/"); * Oper.ResultList.Add("+"); * Oper.ResultList.Add("<"); // в xml: < * Oper.ResultList.Add("<="); // в xml: <= * Oper.ResultList.Add("<>"); // в xml: <> * Oper.ResultList.Add("="); * Oper.ResultList.Add(">"); // в xml: > * Oper.ResultList.Add(">="); // в xml: >= * Oper.ResultList.Add("AND"); * Oper.ResultList.Add("NOT"); * Oper.ResultList.Add("OR"); * Oper.ResultList.Add("XOR"); * Oper.ResultList.Add("1 gain"); * */ }
//отдельный метод для создания тех объекта //надо чтобы создался тех объект со всеми вх/вых каналами (два листа) //надо как-то продумать приинадлежность объекта к цепочке, может в свойствах канала прописывать присваивание public TechObject CreateTechObject(string BaseAddr, string name, int TypeObj) { /*Расшифровка типов объектов: * 0 = объект имеющий марку * 1 = объект не имеющий марки, локальный * 2 = объект типа ссылка * 3 = объект типа TIOCH * */ ConnectToDB connect = new ConnectToDB(); //создаем экземпляр класса для подключения к базе switch (TypeObj) { case 0: //запрос для случая, когда у нас объект с маркой string sql = "select isaobj.name, isaobjfields.name, isaobjfields.tid, isaobjfields.direction, isaobjfields.\"ORDER\" from isaobj, isaobjfields where isaobj.id = (select isacards.tid from isacards where isacards.marka = '" + name + "') and isaobjfields.isaobjid = (select isacards.tid from isacards where isacards.marka = '" + name + "') and isaobjfields.direction <> 3"; //select isaobj.name, isaobjfields.name, isaobjfields.tid, isaobjfields.direction, isaobjfields."ORDER" from isaobj, isaobjfields where isaobj.id = (select isacards.tid from isacards where isacards.marka = 'E_KS7A_034_SEO1_ES1_QF37_L1') and isaobjfields.isaobjid = (select isacards.tid from isacards where isacards.marka = 'E_KS7A_034_SEO1_ES1_QF37_L1') and isaobjfields.direction <> 3 connect.ConnectToBase(sql, BaseAddr); TmpDG = connect.dt1; //в результату получаем пять столбцов в соответствии с запросом //обнаружено, что первый канал улетает в конец, поэтому код ниже работает с учетом этого List <TechObjectChIn> ChInList = new List <TechObjectChIn>(); List <TechObjectChOut> ChOutList = new List <TechObjectChOut>(); //заполним списки входных и выходных каналов для объекта for (int i = 0; i < TmpDG.Rows.Count; i++) { if (Convert.ToInt16(TmpDG.Rows[i][3]) == 1) { TechObjectChIn newChIn = new TechObjectChIn(); newChIn.IndexCh = Convert.ToInt32(TmpDG.Rows[i][4]); newChIn.DataType = Convert.ToInt32(TmpDG.Rows[i][2]); newChIn.NameCh = Convert.ToString(TmpDG.Rows[i][1]); ChInList.Add(newChIn); } if (Convert.ToInt16(TmpDG.Rows[i][3]) == 2) { TechObjectChOut newChOut = new TechObjectChOut(); newChOut.IndexCh = Convert.ToInt32(TmpDG.Rows[i][4]); newChOut.DataType = Convert.ToInt32(TmpDG.Rows[i][2]); newChOut.NameCh = Convert.ToString(TmpDG.Rows[i][1]); ChOutList.Add(newChOut); } } //теперь отсортируем индексы входных каналов, чтобы расположение было как в скаде ChInList.Sort(delegate(TechObjectChIn in1, TechObjectChIn in2) { return(in1.IndexCh.CompareTo(in2.IndexCh)); }); //выходные каналы также отсортируем, плюс к этому, индексы должны начинаться с нуля ChOutList.Sort(delegate(TechObjectChOut out1, TechObjectChOut out2) { return(out1.IndexCh.CompareTo(out2.IndexCh)); }); int tmpIndex = ChOutList[0].IndexCh; foreach (TechObjectChOut out1 in ChOutList) { out1.IndexCh -= tmpIndex; } //создадим сам экземпляр блока TechObject obj = new TechObject(); obj.TechObjectChInList = ChInList; obj.TechObjectChOutList = ChOutList; obj.TypeObject = Convert.ToString(TmpDG.Rows[0][0]); obj.local = false; obj.RefType = false; obj.TIOCHType = false; obj.NameObject = name; obj.T11ID = CounterT11Id; CounterT11Id++; //обязательно увеличиваем счетчик объектов, чтобы не оказалось повторяющихся T11ID TmpDG.Clear(); return(obj); case 1: //запрос для случая, когда у нас объект с маркой sql = "select isaobjfields.name, isaobjfields.tid, isaobjfields.direction, isaobjfields.\"ORDER\" from isaobjfields where isaobjfields.isaobjid = (select isaobj.id from isaobj where isaobj.name = '" + name + "') and isaobjfields.direction <> 3"; //select isaobjfields.name, isaobjfields.tid, isaobjfields.direction, isaobjfields."ORDER" from isaobjfields where isaobjfields.isaobjid = (select isaobj.id from isaobj where isaobj.name = 'Next_AI_SS') and isaobjfields.direction <> 3 connect.ConnectToBase(sql, BaseAddr); TmpDG = connect.dt1; //в результату получаем 4 столбца в соответствии с запросом //обнаружено, что первый канал улетает в конец, поэтому код ниже работает с учетом этого... ChInList = new List <TechObjectChIn>(); ChOutList = new List <TechObjectChOut>(); //заполним списки входных и выходных каналов для объекта for (int i = 0; i < TmpDG.Rows.Count; i++) { if (Convert.ToInt16(TmpDG.Rows[i][2]) == 1) { TechObjectChIn newChIn = new TechObjectChIn(); newChIn.IndexCh = Convert.ToInt32(TmpDG.Rows[i][3]); newChIn.DataType = Convert.ToInt32(TmpDG.Rows[i][1]); newChIn.NameCh = Convert.ToString(TmpDG.Rows[i][0]); ChInList.Add(newChIn); } if (Convert.ToInt16(TmpDG.Rows[i][2]) == 2) { TechObjectChOut newChOut = new TechObjectChOut(); newChOut.IndexCh = Convert.ToInt32(TmpDG.Rows[i][3]); newChOut.DataType = Convert.ToInt32(TmpDG.Rows[i][1]); newChOut.NameCh = Convert.ToString(TmpDG.Rows[i][0]); ChOutList.Add(newChOut); } } //теперь отсортируем индексы входных каналов, чтобы расположение было как в скаде ChInList.Sort(delegate(TechObjectChIn in1, TechObjectChIn in2) { return(in1.IndexCh.CompareTo(in2.IndexCh)); }); //выходные каналы также отсортируем, плюс к этому, индексы должны начинаться с нуля ChOutList.Sort(delegate(TechObjectChOut out1, TechObjectChOut out2) { return(out1.IndexCh.CompareTo(out2.IndexCh)); }); tmpIndex = ChOutList[0].IndexCh; foreach (TechObjectChOut out1 in ChOutList) { out1.IndexCh -= tmpIndex; } //создадим сам экземпляр блока obj = new TechObject(); obj.TechObjectChInList = ChInList; obj.TechObjectChOutList = ChOutList; obj.TypeObject = name; obj.local = true; obj.RefType = false; obj.TIOCHType = false; obj.NameObject = ""; // не забыть переприсвоение в методе определения var!!! obj.T11ID = CounterT11Id; CounterT11Id++; //обязательно увеличиваем счетчик объектов, чтобы не оказалось повторяющихся T11ID TmpDG.Clear(); return(obj); default: throw new Exception(); } //отдельно для случая, когда объект локальный //отдкльно когда ссылка //отдкльно когда канал В/В }
//отдельный метод для создания тех объекта //надо чтобы создался тех объект со всеми вх/вых каналами (два листа) //надо как-то продумать приинадлежность объекта к цепочке, может в свойствах канала прописывать присваивание public TechObject CreateTechObject(string BaseAddr, string name, int TypeObj) { /*Расшифровка типов объектов: * 0 = объект имеющий марку * 1 = объект не имеющий марки, локальный * 2 = объект типа ссылка * 3 = объект типа TIOCH * */ ConnectToDB connect = new ConnectToDB(); //создаем экземпляр класса для подключения к базе switch (TypeObj) { case 0: //запрос для случая, когда у нас объект с маркой string sql = "select isaobj.name, isaobjfields.name, isaobjfields.tid, isaobjfields.direction, isaobjfields.\"ORDER\" from isaobj, isaobjfields where isaobj.id = (select isacards.tid from isacards where isacards.marka = '" + name + "') and isaobjfields.isaobjid = (select isacards.tid from isacards where isacards.marka = '" + name + "') and isaobjfields.direction <> 3"; //select isaobj.name, isaobjfields.name, isaobjfields.tid, isaobjfields.direction, isaobjfields."ORDER" from isaobj, isaobjfields where isaobj.id = (select isacards.tid from isacards where isacards.marka = 'E_KS7A_034_SEO1_ES1_QF37_L1') and isaobjfields.isaobjid = (select isacards.tid from isacards where isacards.marka = 'E_KS7A_034_SEO1_ES1_QF37_L1') and isaobjfields.direction <> 3 connect.ConnectToBase(sql, BaseAddr); TmpDG = connect.dt1; //в результату получаем пять столбцов в соответствии с запросом //обнаружено, что первый канал улетает в конец, поэтому код ниже работает с учетом этого List <TechObjectChIn> ChInList = new List <TechObjectChIn>(); List <TechObjectChOut> ChOutList = new List <TechObjectChOut>(); //заполним списки входных и выходных каналов для объекта for (int i = 0; i < TmpDG.Rows.Count; i++) { if (Convert.ToInt16(TmpDG.Rows[i][3]) == 1) { TechObjectChIn newChIn = new TechObjectChIn(); newChIn.IndexCh = Convert.ToInt32(TmpDG.Rows[i][4]); newChIn.DataType = Convert.ToInt32(TmpDG.Rows[i][2]); newChIn.NameCh = Convert.ToString(TmpDG.Rows[i][1]); ChInList.Add(newChIn); } if (Convert.ToInt16(TmpDG.Rows[i][3]) == 2) { TechObjectChOut newChOut = new TechObjectChOut(); newChOut.IndexCh = Convert.ToInt32(TmpDG.Rows[i][4]); newChOut.DataType = Convert.ToInt32(TmpDG.Rows[i][2]); newChOut.NameCh = Convert.ToString(TmpDG.Rows[i][1]); ChOutList.Add(newChOut); } } //теперь отсортируем индексы входных каналов, чтобы расположение было как в скаде ChInList.Sort(delegate(TechObjectChIn in1, TechObjectChIn in2) { return(in1.IndexCh.CompareTo(in2.IndexCh)); }); //выходные каналы также отсортируем, плюс к этому, индексы должны начинаться с нуля ChOutList.Sort(delegate(TechObjectChOut out1, TechObjectChOut out2) { return(out1.IndexCh.CompareTo(out2.IndexCh)); }); int tmpIndex = ChOutList[0].IndexCh; foreach (TechObjectChOut out1 in ChOutList) { out1.IndexCh -= tmpIndex; } //создадим сам экземпляр блока TechObject obj = new TechObject(); obj.TechObjectChInList = ChInList; obj.TechObjectChOutList = ChOutList; obj.TypeObject = Convert.ToString(TmpDG.Rows[0][0]); obj.local = false; obj.RefType = false; obj.TIOCHType = false; obj.NameObject = name; obj.T11ID = CounterT11Id; CounterT11Id++; //обязательно увеличиваем счетчик объектов, чтобы не оказалось повторяющихся T11ID TmpDG.Clear(); return(obj); case 1: //запрос для случая, когда у нас объект с маркой sql = "select isaobjfields.name, isaobjfields.tid, isaobjfields.direction, isaobjfields.\"ORDER\" from isaobjfields where isaobjfields.isaobjid = (select isaobj.id from isaobj where isaobj.name = '" + name + "') and isaobjfields.direction <> 3"; //select isaobjfields.name, isaobjfields.tid, isaobjfields.direction, isaobjfields."ORDER" from isaobjfields where isaobjfields.isaobjid = (select isaobj.id from isaobj where isaobj.name = 'Next_AI_SS') and isaobjfields.direction <> 3 connect.ConnectToBase(sql, BaseAddr); TmpDG = connect.dt1; //в результату получаем 4 столбца в соответствии с запросом //обнаружено, что первый канал улетает в конец, поэтому код ниже работает с учетом этого... ChInList = new List <TechObjectChIn>(); ChOutList = new List <TechObjectChOut>(); //заполним списки входных и выходных каналов для объекта for (int i = 0; i < TmpDG.Rows.Count; i++) { if (Convert.ToInt16(TmpDG.Rows[i][2]) == 1) { TechObjectChIn newChIn = new TechObjectChIn(); newChIn.IndexCh = Convert.ToInt32(TmpDG.Rows[i][3]); newChIn.DataType = Convert.ToInt32(TmpDG.Rows[i][1]); newChIn.NameCh = Convert.ToString(TmpDG.Rows[i][0]); ChInList.Add(newChIn); } if (Convert.ToInt16(TmpDG.Rows[i][2]) == 2) { TechObjectChOut newChOut = new TechObjectChOut(); newChOut.IndexCh = Convert.ToInt32(TmpDG.Rows[i][3]); newChOut.DataType = Convert.ToInt32(TmpDG.Rows[i][1]); newChOut.NameCh = Convert.ToString(TmpDG.Rows[i][0]); ChOutList.Add(newChOut); } } //теперь отсортируем индексы входных каналов, чтобы расположение было как в скаде ChInList.Sort(delegate(TechObjectChIn in1, TechObjectChIn in2) { return(in1.IndexCh.CompareTo(in2.IndexCh)); }); //выходные каналы также отсортируем, плюс к этому, индексы должны начинаться с нуля ChOutList.Sort(delegate(TechObjectChOut out1, TechObjectChOut out2) { return(out1.IndexCh.CompareTo(out2.IndexCh)); }); tmpIndex = ChOutList[0].IndexCh; foreach (TechObjectChOut out1 in ChOutList) { out1.IndexCh -= tmpIndex; } //создадим сам экземпляр блока obj = new TechObject(); obj.TechObjectChInList = ChInList; obj.TechObjectChOutList = ChOutList; obj.TypeObject = name; obj.local = true; obj.RefType = false; obj.TIOCHType = false; obj.NameObject = ""; // не забыть переприсвоение в методе определения var!!! obj.T11ID = CounterT11Id; CounterT11Id++; //обязательно увеличиваем счетчик объектов, чтобы не оказалось повторяющихся T11ID TmpDG.Clear(); return(obj); case 2: string tmpPLCName = ""; string tmpResName = ""; string tmpObjectName = ""; string tmpChName = ""; string tmpChChName = ""; //это канал блока ссылки, поэтому канал канала. string tmpStr = ""; //буферная переменная List <string> tmpList = new List <string>(); // лист для элементов подстроки //далее посимвольно разберем на лист for (int j = 0; j < name.Length; j++) { if (name[j] == Convert.ToChar(@"\")) //СОМНИТЕЛЬНЫЙ ПРИЁМ, ПРОВЕРИТЬ { tmpList.Add(tmpStr); tmpStr = ""; continue; } tmpStr += name[j]; } //заполняем элементы ссылки. if (tmpList.Count == 4) { tmpPLCName = tmpList[0]; tmpResName = tmpList[1]; tmpObjectName = tmpList[2]; tmpChName = tmpList[3]; // select cards.marka, cards.objtypeid, cards.plc_gr, cards.plc_id, objtypeparam.name, objtypeparam.valtype, objtypeparam.ismanual from cards, objtypeparam where cards.marka = 'E_KS7A_034_SEO1_XX4_ALR' and objtypeparam.name = '.In' and objtypeparam.pid = (select cards.objtypeid from cards where cards.marka = 'E_KS7A_034_SEO1_XX4_ALR'); //если прочитался, имя объекта и канал существуют, и можно выгрузить тип данных, //select cards.marka, resources.name from cards, resources where cards.id = 439 and resources.id = 14; //из результатов предыдущего запроса вставляем в 439 cards.plc_id, а в 14 - cards.plc_gr. //Получив имя контроллера и ресурса, сравниваем с текстом ссылки и пляшем дальше. //запрос для проверки канала и объекта sql = "select cards.marka, cards.objtypeid, cards.plc_gr, cards.plc_id, objtypeparam.name, objtypeparam.valtype, objtypeparam.ismanual from cards, objtypeparam where cards.marka = '" + tmpObjectName + "' and objtypeparam.name = '" + tmpChName + "' and objtypeparam.pid = (select cards.objtypeid from cards where cards.marka = '" + tmpObjectName + "')"; // select cards.marka, cards.objtypeid, cards.plc_gr, cards.plc_id, objtypeparam.name, objtypeparam.valtype, objtypeparam.ismanual from cards, objtypeparam where cards.marka = 'E_KS7A_034_SEO1_XX4_ALR' and objtypeparam.name = '.In' and objtypeparam.pid = (select cards.objtypeid from cards where cards.marka = 'E_KS7A_034_SEO1_XX4_ALR'); connect.ConnectToBase(sql, BaseAddr); TmpDG = connect.dt1; //в результату получаем 7 столбцов в соответствии с запросом string tmpPLC_GR = Convert.ToString(TmpDG.Rows[0][2]); //id ресурса, полученный из запроса string tmpPLC_ID = Convert.ToString(TmpDG.Rows[0][3]); //id ПЛК полученный из запроса int dataType = Convert.ToInt32(TmpDG.Rows[0][5]); //тип данных, полученный из запроса bool isManual = Convert.ToBoolean(TmpDG.Rows[0][6]); //флаг того, что ссылка позволяет в неё что-то записать TmpDG.Clear(); //Если запрос комбинации марка + имя канала не существует, то ответ будет нулевым и программа крашнется //надо потом сделать исключение //Если ответ нормальный, то шлём следующий запрос для проверки принадлежности нужному ресурсу и контроллеру sql = "select cards.marka, resources.name from cards, resources where cards.id = " + tmpPLC_ID + " and resources.id = " + tmpPLC_GR; if ((tmpPLCName == Convert.ToString(TmpDG.Rows[0][0])) && (tmpResName == Convert.ToString(TmpDG.Rows[0][1]))) { //создадим полноценный объект с каналами ввода/вывода obj = new TechObject(); if (isManual) { TechObjectChIn chIn = new TechObjectChIn(); chIn.DataType = dataType; chIn.IndexCh = 0; chIn.NameCh = "In"; //временное название, пока неизвестно, что в реальности нужно obj.TechObjectChInList.Add(chIn); } //всегда два выходных канала первый - это просто выход с такими же характеристиками как и вход. TechObjectChOut chOut1 = new TechObjectChOut(); chOut1.DataType = dataType; chOut1.IndexCh = 0; chOut1.NameCh = "Out"; //второй канал всегда качество, типа int TechObjectChOut chOut2 = new TechObjectChOut(); chOut2.DataType = 5; chOut2.IndexCh = 1; chOut2.NameCh = "Q"; //реальное имя канала obj.TechObjectChOutList.Add(chOut1); obj.TechObjectChOutList.Add(chOut2); //создадим сам объект obj = new TechObject(); obj.NameObject = name; obj.RefType = true; obj.T11ID = CounterT11Id; CounterT11Id++; return(obj); } else { throw new Exception(); } } else { throw new Exception(); } case 3: //запрос для проверки канала и объекта sql = "select isacards.marka, isacards.classid, isacards.resid from isacards where isacards.name = '" + name + "'"; // select isacards.marka, isacards.classid, isacards.resid from isacards where isacards.name = '[COM1013:16:31] mb_master_hr_int_out_v > êàíàë 0' connect.ConnectToBase(sql, BaseAddr); TmpDG = connect.dt1; //в результату получаем 3 столбцов в соответствии с запросом if (Convert.ToInt32(TmpDG.Rows[0][2]) == ResID) { obj = new TechObject(); string tmpMarka = ""; int tmpClassID = 0; int tmpResID = 0; //class id = 2 --> только выход, class id = 3 --> вход/выход //если есть входной канал, то добавим его в объект if (Convert.ToInt32(TmpDG.Rows[0][1]) == 3) { TechObjectChIn ChIn = new TechObjectChIn(); ChIn.IndexCh = 0; ChIn.NameCh = "In"; //newChIn.DataType = ПРИСВАИВАТЬ В МЕТОДЕ ПОИСКА СОВПАДЕНИЙ obj.TechObjectChInList.Add(ChIn); } //всег овозможно 4 выходных канала, присвоим их сразу TechObjectChOut ChOut = new TechObjectChOut(); //Добавим 4 канала в объект вручную. ChOut.IndexCh = 0; ChOut.NameCh = "Status"; ChOut.DataType = 6; obj.TechObjectChOutList.Add(ChOut); ChOut.IndexCh = 1; ChOut.NameCh = "ValueBOOL"; ChOut.DataType = 9; obj.TechObjectChOutList.Add(ChOut); ChOut.IndexCh = 2; ChOut.NameCh = "ValueDINT"; ChOut.DataType = 6; obj.TechObjectChOutList.Add(ChOut); ChOut.IndexCh = 3; ChOut.NameCh = "ValueREAL"; ChOut.DataType = 7; obj.TechObjectChOutList.Add(ChOut); //!!! В ЦИКЛЕ ДОБАВИТЬ СТОЛЬКО ЖЕ ВНУТРЕННИХ КАНАЛОВ, ЧТОБЫ //ПОТОМ ОСТАВАЛОСЬ ТОЛЬКО ВЫБРАТЬ obj.TIOCHType = true; obj.NameObject = Convert.ToString(TmpDG.Rows[0][0]); obj.T11ID = CounterT11Id; CounterT11Id++; return(obj); } else { throw new Exception(); } default: throw new Exception(); } //отдельно для случая, когда объект локальный //отдкльно когда ссылка //отдкльно когда канал В/В }