Форум программистов, компьютерный форум, киберфорум
АСУ ТП, промэлектроника
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.69/193: Рейтинг темы: голосов - 193, средняя оценка - 4.69
53 / 53 / 2
Регистрация: 30.05.2014
Сообщений: 83

OPC клиент (OPC_DA v2.05) для платформы NET

12.10.2014, 22:35. Показов 43639. Ответов 51
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Предлагаю следующую библиотеку для обмена данными с OPC сервером в приложении NET.

Библиотека "OPC_NET" представляет OPC клиент для платформы NET и предназначена для легкого обмена с любыми OPC серверами поддерживающими стандарт OPC_DA v2.05. Основана на SDK OpcNetApi организации OPC Foundation - разработчика стандарта.
Данные для обмена объявляются в файле типа xlsx. Данные читаются и пишутся по именам заданным в этом файле.

Пример работы:

1. Заполнение таблицы сигналов



2. Соединение с сервером
C#
1
2
3
4
5
6
7
8
  // создаем клиент
   OPC_NET.OPCclient cl = new OPC_NET.OPCclient();
 
  // объявляем переменные     
   cl.Init(@".\TableSignal.xlsx");
 
  // запрос на соединение с сервером
    int er =  cl.ConnectOpcServer(_ipAddrOPCserver, _nameOPCserver, _timeUpdDataOPCserver);
3. Читаем значения переменных:
C#
1
2
3
4
5
6
7
8
9
       bool err;
           
    bool val0 =  cl.ReadBool("enaFW", out err);
 
    int val1 =  cl.ReadInt16("driveFlt", out err);
 
    int val2 =  cl.ReadInt32("sensorFlt", out err);
 
    double val3 = cl.ReadReal("pressure", out err);
4. Пишем значения переменных:
C#
1
2
3
4
5
    bool err;
           
     cl.WriteInt16("dag", 34, out err);
 
     cl.WriteBool("sensEna", true, out err);

Скачать (исходник и мануал прилагаются):OPC_NET_RUS_V1.0.rar

PS: буду благодарен, если кто поделится этим чудом - ".NET4.0(WCF)" от OPC Foundation (https://opcfoundation.org/deve... et-4-0-wcf). Сразу перепишу либу на новый лад.

Изменения версии 1.11:
- переделаны события изменения данных: удалены события конкретных типов и создано общее событие – содержащее информацию обо всех измененных переменных;
- в классе Items добавлены несколько методов для коллекции объектов;
- открыты перечисления для входных числовых значений;
- переименованы некоторые объекты;

Скачать (исходник и мануал прилагаются): OPC_NET_RUS_V1.11.rar

Прошу добавить в заголовок темы, а то сам тему изменить не могу.
5
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.10.2014, 22:35
Ответы с готовыми решениями:

OPC клиент для сохранения данных с OPC сервера
Добрый день! Подскажите библиотеку для создания OPC клиента или возможно есть готовый OPC клиент, сохраняющий опрошенные данные?

ASP.net OPC клиент
Я подключаю dll-ки к проекту web-forms OpcNetApi.dll то есть делаю opc-клиент. при разработке все работает теги принимаю как запускаю...

OPC DA клиент на библиотеках OPC Foundation
Народ, подскажите pls, если кто знает... Написал пробного OPC клиента на C#, использовал библиотеки от OPC Foundation OpcNetApi.Com.dll и...

51
3 / 3 / 1
Регистрация: 18.12.2014
Сообщений: 74
21.04.2017, 07:47
Студворк — интернет-сервис помощи студентам
при подключении к opc, 0 возвращается? там есть ещё функция проверки переменных! попробуйте её ещё, она тоже если всё верно должна 0 возвратить! на овне не тестил, а на siemens всё работает как надо)
0
0 / 0 / 0
Регистрация: 28.02.2017
Сообщений: 9
21.04.2017, 11:54
Попробую заново создам проект. На win 7 x64 базовой может работать или обязательно нужна х32 ?
0
3 / 3 / 1
Регистрация: 18.12.2014
Сообщений: 74
21.04.2017, 12:34
нет, работает и на x64, скомпилируй проект под x86, c Any CPU не запускалось у меня на x64
1
0 / 0 / 0
Регистрация: 28.02.2017
Сообщений: 9
22.04.2017, 13:27
Цитата Сообщение от Leo28 Посмотреть сообщение
при подключении к opc, 0 возвращается? там есть ещё функция проверки переменных! попробуйте её ещё, она тоже если всё верно должна 0 возвратить!
С сервером коннектится, возвращает 0, но когда пытаюсь прочитать переменную напрямую err принимает значение true, т.е. с сервера не читает.

Добавлено через 14 часов 17 минут
Похоже ошибка появляется из-за прописанного тега Com4/TRM201v24(8bit adr=0)/LvoP/Pv До этого пробовал на 3х других OPC клиентах, всё нормально читается. Собственно вопрос, как в этом клиенте правильно задавать переменные для сервера OWEN.RS485, или придётся в сам клиент какие-то изменения вносить?

Добавлено через 2 часа 11 минут
Всё заработало когда прописал переменные через TableSignal4.xml
0
0 / 0 / 0
Регистрация: 28.02.2017
Сообщений: 9
23.04.2017, 13:52
Подскажите, когда на подписку ставлю больше одного тега, значения перестают автоматически обновляться, может что-то не так делаю?
0
 Аватар для Spectral-Owl
608 / 583 / 157
Регистрация: 29.06.2010
Сообщений: 1,620
21.03.2018, 12:00
Возможно я пинаю труп, но решил попробовать что за оно.

OPC_NET.OPCclient использовать не стал, не понравилось что у события приёма данных отсутствуют биты качества и метка времени.

т.е. остались нужны всего две из выложенных библиотек: OpcNetApi.Com.dll и OpcNetApi.dll

дальше, для конкретного OPC сервера получил все его элементы и подписался на обновления (код в WPF, немного изменил то, что представил EVG-1980):

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
        //поля для связи с сервером: сам сервер, его подписка, и фильтр
        private Opc.Da.Server server;
        private Opc.Da.ISubscription subscription;
        private Opc.Da.BrowseFilters filters;
 
        //коллекция добавленных в подписку тэгов
        Dictionary<string, TreeViewItem> tags = new Dictionary<string, TreeViewItem>();
 
        public MainWindow()
        {
            InitializeComponent();
 
            //получение текущего IP
            string strip = "127.0.0.1";
            String host = System.Net.Dns.GetHostName();
            System.Net.IPAddress ip = System.Net.Dns.GetHostByName(host).AddressList[0];
            strip = ip.ToString();
 
            //строка коннекта
            Opc.URL url = new Opc.URL("opcda://" + strip + "/" + OpcName);
 
            //создание и подключение сервера
            OpcCom.Factory fact = new OpcCom.Factory();
            server = new Opc.Da.Server(fact, null);
            server.Connect(url, new Opc.ConnectData(new System.Net.NetworkCredential()));
 
            //создание подписки
            server.Subscriptions.Clear();
            subscription = server.CreateSubscription(new Opc.Da.SubscriptionState());
            subscription.DataChanged += Subscription_DataChanged;
 
            //обзор содержимого сервера
            filters = new Opc.Da.BrowseFilters() { BrowseFilter = Opc.Da.browseFilter.all };
            browseserver(null, null);  
        }
        
        //рекурсивный метод просмотра содержимого сервера
        private void browseserver(TreeViewItem node, Opc.Da.BrowseElement parent)
        {
            try {
                //выход на уровень повыше, если достигнут конечный элемент
                if (parent != null && parent.IsItem)
                    return;
 
                //получение инфы о текущем объекте
                Opc.ItemIdentifier ItemID = null;
                if (node != null && node.Tag != null && node.Tag.GetType() == typeof(Opc.Da.BrowseElement)) {
                    parent = (Opc.Da.BrowseElement)node.Tag;
                    ItemID = new Opc.ItemIdentifier(parent.ItemPath, parent.ItemName);
                }
 
                //получение дочерних объектов
                Opc.Da.BrowsePosition position = null;
                Opc.Da.BrowseElement[] elements = server.Browse(ItemID, filters, out position);
                
                if (elements != null) {
                    foreach (Opc.Da.BrowseElement element in elements) {
                        //добавление дочернего объекта
                        TreeViewItem newnode = createcontrol(node, element);
                        //просмотр содержимого дочернего объекта
                        browseserver(newnode, element);
                    }
                }
            }
            catch (Exception e) { MessageBox.Show(e.Message); }
        }
 
        //создание нода для объекта
        private TreeViewItem createcontrol(TreeViewItem _parent, Opc.Da.BrowseElement element)
        {
            //создание нода
            TreeViewItem node = new TreeViewItem();
            node.Header = element.Name;
            node.Tag = element;
 
            //добавление нода на экран
            if (_parent == null)
                tv1.Items.Add(node);//tv1 - TreeView, корневые ноды добавляются в него
            else _parent.Items.Add(node);
 
            //если объект - тэг, а не папка..
            if (element.IsItem) {
                //получение инфы для подписки
                Opc.Da.Item item = new Opc.Da.Item(new Opc.ItemIdentifier(element.ItemPath, element.ItemName));
                //добавление подписки
                Opc.Da.ItemResult[] result = subscription.AddItems(new Opc.Da.Item[] { item });
                //анализ подписки на ошибки
                foreach (var res in result)
                    if (res.ResultID.Code != 0)
                        MessageBox.Show(res.ResultID.ToString());
                //добавление тэга в коллекцию
                tags.Add(element.ItemName, node);
            }
            //возврат созданного нода
            return node;
        }
        
        //обработчик события принятия данных подписки
        private void Subscription_DataChanged(object subscriptionHandle, object requestHandle, Opc.Da.ItemValueResult[] values)
        {
            //возврат в основной поток
            Dispatcher.Invoke(new System.Threading.ThreadStart(() => {
                //для всех принятых данных
                foreach (var val in values)
                    //если они не null (разок видел, удивился)
                    if (val != null && val.ItemName != null)
                        //отображение состояния
                        tags[val.ItemName].Header = val.Timestamp.ToLongTimeString() + " {" + val.Quality.QualityBits.ToString() + "} " + val.ItemName + " = " + val.Value;
            }));
        }
и вроде-бы всё замечательно и всё работает, даже захотел использовать данную либу в своём OPC клиенте, добавил указанные библиотеки, всё сделал в общем, и столкнулся с проблемой:

Opc.Da.BrowseElement.IsItem всегда false. Чёрт его знает чего. Пробовал переносить рабочие куски кода, пересоздавать окна, переписывать код вручную заново, даже перезагружать студию и комп, не помогает =(

следовательно две проблеммы:
1) в методе browseserver не срабатывает выход на уровень наверх, рекурсия не прерывается (ну как, прерывается, т.к. сервер при попытке просмотреть дочерние элементы тэга сыпет ошибки).
2) в методе createcontrol не происходит подписка на тэг, что печально.

пробовал анализировать не только свойство IsItem, но и HasChildren. Проблему 1 это исправляет, проблема 2 начинает сыпать ошибками 0x80020008 (несоответствие типа вроде)

сталкивался ли кто с такой фигнёй? Либо может идеи есть? и да, может стоило не некропостить, а новую тему создать (хотя вопросы по выложенным в теме либам)? в общем, одни вопросы)

Добавлено через 45 минут
Опаньки, нашел как всё поломать:
свойства проекта, изменить требуемую версию Framework с 4.5.2 на любую другую. Всё. Потом, даже если выполнить обратное действие, всё останется поломанным, даже удаление и добавление ссылок на библиотеки заново не помогает. Я, честно говоря, в недоумении. Вопросов стало ещё больше.

Добавлено через 1 час 12 минут
ну, и немного ещё:

если использовать OPC_NET.OPCClient и поменять версию Framework все вышеназванные проблемы сохраняются:
C#
1
2
3
4
5
6
7
            OPC_NET.Items items = client.GetItems();
            OPC_NET.VarData vd = new OPC_NET.VarData();
            vd.Address = "GRP-1/IO/AI/AI4";
            vd.Name = "ai4";
            vd.TypeRW = OPC_NET.TypeRW.Read;
            vd.Value = 0.0;
            items.Add(new List<OPC_NET.VarData> { vd }, out erradd);
items.OpcReadResult.ResultID равен 0x80020008 и т.д.

и ещё заметил, после коннекта Opc.Da.Server.GetState() выбрасывает FatalExecutionEngineError даже находясь внутри try{}catch{}
1
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
21.03.2018, 17:19
радуйтесь. этож .NET . Когда Allen Bradley затевали тему OPC, подобной лабуды в помине не было. Все прекрасно справлялись с COM/DCOM. Причем, даже delphi'сты (в лице, например, меня), где COM-объекты выглядят не так красиво как в C++.
0
 Аватар для Spectral-Owl
608 / 583 / 157
Регистрация: 29.06.2010
Сообщений: 1,620
22.03.2018, 08:36
уря) я починиль!)
сначала скажу что наткнулся на эту страницу, где в ветке downloads скачал OPC client for WPF. Увидел очень похожие исходники, только с комментариями на английском, да и версия у встроенных dll подревнее была))
Так вот, к чему это я: в скаченном проекте указанные мною действия к проблемам не приводили, всё продолжало работать. Поплясав с бубном в поисках разницы в проектах увидел, чтоб всё работало, конечная платформа должна иметь тип x86, а не AnyCPU, как было по умолчанию.

Теперь походу нужно будет тестить в разных виндах...
0
53 / 53 / 2
Регистрация: 30.05.2014
Сообщений: 83
31.03.2018, 16:51  [ТС]
переходите на плюсы, нах этот net.
на плюсах все гораздо проще, нет кучи прослоек и интфейсов.
0
23.12.2018, 19:37  [ТС]

Не по теме:


Для мониторинга-записи сигналов предлагаю воспользоваться системой "SVisual" - тоже моя разработка.
Интерфейс и мануал на русском, все открыто и бесплатно.

С целью продвижения оставлю ссылку : https://github.com/Tyill/SVisual/releases
Ставьте звездочки на github-е, если понравится.

Пример мониторинга сигналов после получения с ПЛК:

Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
 
namespace SV
{
 public unsafe class Client
 {
 [DllImport("SVClient.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
     static extern bool svConnect([MarshalAs(UnmanagedType.LPStr)]string moduleName, [MarshalAs(UnmanagedType.LPStr)]string ipaddr, int port);
 
 public bool connect(string moduleName, string ipaddr, int port)
 {
     return svConnect(moduleName, ipaddr, port);
 }
 
 [DllImport("SVClient.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
 static extern void svDisconnect();
 
 public void disconnect()
 {
     svDisconnect();
 }
 
 [DllImport("SVClient.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
 static extern bool svAddBoolValue([MarshalAs(UnmanagedType.LPStr)]string name, bool value, bool onlyFront);
 
 public bool addBoolValue(string name, bool value, bool onlyFront)
 {
     return svAddBoolValue(name, value, onlyFront);
 }
     
 [DllImport("SVClient.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
 static extern bool svAddIntValue([MarshalAs(UnmanagedType.LPStr)]string name, int value);
 
 public bool addIntValue(string name, int value)
 {
     return svAddIntValue(name, value);
 }
 
 [DllImport("SVClient.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
 static extern bool svAddFloatValue([MarshalAs(UnmanagedType.LPStr)]string name, float value);
 
 public bool addFloatValue(string name, float value)
 {
     return svAddFloatValue(name, value);
 }
 
 };
};
 
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
                                        
            // соединение с OPC
            OPC_NET.OPCclient cl = new OPC_NET.OPCclient();
            cl.Init(@".\TableSignal.xlsx");
 
            int er =  cl.ConnectOpcServer("???.?.?.?", ???, 100);
 
            // соединение с монитором
            SV.Client clMon = new SV.Client();
            clMon.connect("fromPLC", "127.0.0.1", 2144);
            
            while (true)    
            {
                // читаем данные с OPC
                bool err;    
                int val =  cl.ReadInt16("Speed", out err);
 
                // передаем на монитор
                clMon.addIntValue("Speed", val);
               
                System.Threading.Thread.Sleep(100);
            }
        }
    }
}


SVClient.dll - это библиотека для отправки данных на монитор, написана на C++, поэтому сверху обертка для C#.
Находится рядом с дистрибутивом в архиве cpp_client.rar.
Сам только проверить на ПЛК не могу, не связан с автоматикой сейчас. Пишите в комментариях этой темы, что получилось-нет.

0
1 / 1 / 1
Регистрация: 19.03.2020
Сообщений: 10
05.04.2020, 13:41
Цитата Сообщение от Spectral-Owl Посмотреть сообщение
Opc.Da.BrowseElement.IsItem всегда false. Чёрт его знает чего. Пробовал переносить рабочие куски кода, пересоздавать окна, переписывать код вручную заново, даже перезагружать студию и комп, не помогает =(
следовательно две проблеммы:
1) в методе browseserver не срабатывает выход на уровень наверх, рекурсия не прерывается (ну как, прерывается, т.к. сервер при попытке просмотреть дочерние элементы тэга сыпет ошибки).
2) в методе createcontrol не происходит подписка на тэг, что печально.
пробовал анализировать не только свойство IsItem, но и HasChildren. Проблему 1 это исправляет, проблема 2 начинает сыпать ошибками 0x80020008 (несоответствие типа вроде)
сталкивался ли кто с такой фигнёй? Либо может идеи есть? и да, может стоило не некропостить, а новую тему создать (хотя вопросы по выложенным в теме либам)? в общем, одни вопросы)
Эту программу проверил под WIndows Forms. Адаптировал и всё работает, указанных проблем нет. Платформа AnyCPU

ВОт так выглядит у меня метод BrowseServer

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
        
private void BrowseServer(TreeNode node, Opc.Da.BrowseElement parent)            
        {
            Opc.Da.BrowseFilters bf = new Opc.Da.BrowseFilters();
            bf.BrowseFilter = browseFilter.all;
            try
            {
                //выход на уровень повыше, если достигнут конечный элемент
              //  if (parent != null && parent.IsItem) return;
 
                //получение инфы о текущем объекте
                Opc.ItemIdentifier itemID = null;
                if (node != null && node.Tag != null && node.Tag.GetType() == typeof(Opc.Da.BrowseElement))
                    itemID = new Opc.ItemIdentifier(parent.ItemPath, parent.ItemName);
                //получение дочерних объектов
                Opc.Da.BrowsePosition position = null; // position всё время возвращает нулевое значение. Не нужная переменная
                Opc.Da.BrowseElement[] elements = server.Browse(itemID, bf, out position); //Просматривает содержимое тэга ItemID
 
                if (elements != null) // если элементов больше нет, то начинаем подниматься наверх
                {
 
                    foreach (Opc.Da.BrowseElement element in elements)
                    {
                        TreeNode newnode = new TreeNode();
                        Item item = new Item();
                        //добавление дочернего объекта                        
 
                        newnode.Text = element.Name; // создание нода дочернего объекта
                        newnode.Tag = element;
 
                        //добавление нода на экран
                        if (node == null)
                            treeView1.Nodes.Add(newnode);// Если находимся в корне
                        else node.Nodes.Add(newnode);
                                                   
                        //если объект - тэг, а не папка..
                        if (element.IsItem)
                        {
                            //добавление тэга в коллекцию
                            item.ItemName = element.ItemName;
                            item.Active = true;
                            item.ActiveSpecified = true;
                            Items.Add(item);
                            //Tags.Add(element.ItemName, newnode);                            
                            listBox1.Items.Add(element.Name);
                        }
 
                        //просмотр содержимого дочернего объекта, если он есть
                        if (element.HasChildren) BrowseServer(newnode, element); // рекурсивный вызов функции
                    }
                }                
            }
            catch (Exception e) { MessageBox.Show(e.Message); }
        }
0
0 / 0 / 0
Регистрация: 19.09.2024
Сообщений: 3
19.09.2024, 23:03
Что такое N7:0,L2 в подключении в RSLinx OPC Server??
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.09.2024, 23:03
Помогаю со студенческими работами здесь

Использование OPC-сервера от OPC Foundation (.NET)
Всем привет, возникла необходимость в разработке OPC DA 2.05a сервера под .NET, среди бесплатных вариантов ничего не нашел, писать...

Клиент OPC DA для Quantum
Добрый день всем! Мне необходимо создать клиента для обмена данными с контроллерами Quantum (Schneider Electric) через OPC DA. Опыт...

OPC UA Клиент для работы с TeslaScada2 в Debian
Здравствуйте. Я создал проект в TeslaSCADA2 IDE, создал там Modbus сервер, тэг, на всякий случай цифровой дисплей для вывода результата....

Клиент для OPC сервер Kepware и удаленное подключение
Добрый день, подскажите пожалуйста. Есть маленький клиент на c#, который читает значения тегов и записывает в них значения. Сервер OPC...

Выпущен официальный ICQ-клиент для платформы Android
Интернет-сервис ICQ объявил о выпуске официального клиента ICQ Mobile для смартфонов под управлением операционной системы Android. ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
52
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru