• Как конвертировать ObservableCollection в DataTable?

    k1lex
    @k1lex Автор вопроса
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    В итоге решил так (код взят из интернета).
    Относительно универсальный конвертер LIST в DataTable
    public DataTable ToDataTable<T>(List<T> items)
            {
                var tb = new DataTable(typeof(T).Name);
    
                PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
    
                foreach (PropertyInfo prop in props)
                {
                    Type t = GetCoreType(prop.PropertyType);
                    tb.Columns.Add(prop.Name, t);
                }
    
    
                foreach (T item in items)
                {
                    var values = new object[props.Length];
    
                    for (int i = 0; i < props.Length; i++)
                    {
                        values[i] = props[i].GetValue(item, null);
                    }
    
                    tb.Rows.Add(values);
                }    return tb;
            }
    
     public static bool IsNullable(Type t)
            {
                return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
            }
    
     public static Type GetCoreType(Type t)
            {
                if (t != null && IsNullable(t))
                {
                    if (!t.IsValueType)
                    {
                        return t;
                    }
                    else
                    {
                        return Nullable.GetUnderlyingType(t);
                    }
                }
                else
                {
                    return t;
                }
            }
    Ответ написан
  • Как реализовать множественный фильтр данных?

    k1lex
    @k1lex Автор вопроса
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Задачу решил сам поочередной проверкой условий.
    private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
            {
                cgAssortment cgA = e.Item as cgAssortment;
                bool isAccept = true;
    
                if (cgA != null)
                {
                    try
                    {
                        isAccept = isAccept && (!this.cbOnLink.IsChecked.Value || (this.cbOnLink.IsChecked == true && (cgA.Group5GUID == null)));
                        isAccept = isAccept && (!this.cbInMatrix.IsChecked.Value || (this.cbInMatrix.IsChecked == true && (cgA.InMatrix == true)));
                        isAccept = isAccept && (!this.dgGoodsAllF1.IsChecked.Value || (this.dgGoodsAllF1.IsChecked.Value && cgA.Code.ToString() == this.dgGoodsAllT1.Text));
                        isAccept = isAccept && (!this.dgGoodsAllF2.IsChecked.Value || (this.dgGoodsAllF2.IsChecked.Value && (cgA.NameLong.ToUpper().Contains(this.dgGoodsAllT2.Text.ToUpper()))));
                        isAccept = isAccept && (!this.dgGoodsAllF3.IsChecked.Value || (this.dgGoodsAllF3.IsChecked.Value && (cgA.cgGroup2.NameLong.ToUpper().Contains(this.dgGoodsAllT3.Text.ToUpper()))));
                        isAccept = isAccept && (!this.dgGoodsAllF4.IsChecked.Value || (this.dgGoodsAllF4.IsChecked.Value && cgA.cgGroup3 != null && (cgA.cgGroup3.NameLong.ToUpper().Contains(this.dgGoodsAllT4.Text.ToUpper()))));
                        isAccept = isAccept && (!this.dgGoodsAllF5.IsChecked.Value || (this.dgGoodsAllF5.IsChecked.Value && cgA.cgGroup4 != null && (cgA.cgGroup4.NameLong.ToUpper().Contains(this.dgGoodsAllT5.Text.ToUpper()))));
                        isAccept = isAccept && (!this.dgGoodsAllF6.IsChecked.Value || (this.dgGoodsAllF6.IsChecked.Value && cgA.cgGroup5 != null && (cgA.cgGroup5.NameLong.ToUpper().Contains(this.dgGoodsAllT6.Text.ToUpper()))));
                        isAccept = isAccept && (!this.dgGoodsAllF7.IsChecked.Value || (this.dgGoodsAllF7.IsChecked.Value && cgA.cgGroup6 != null && (cgA.cgGroup6.NameLong.ToUpper().Contains(this.dgGoodsAllT7.Text.ToUpper()))));
                        isAccept = isAccept && (!this.dgGoodsAllF8.IsChecked.Value || (this.dgGoodsAllF8.IsChecked.Value && cgA.cgGroup7 != null && (cgA.cgGroup7.NameLong.ToUpper().Contains(this.dgGoodsAllT8.Text.ToUpper()))));
                        isAccept = isAccept && (!this.dgGoodsAllF9.IsChecked.Value || (this.dgGoodsAllF9.IsChecked.Value && cgA.cgGroup8 != null && (cgA.cgGroup8.NameLong.ToUpper().Contains(this.dgGoodsAllT9.Text.ToUpper()))));
                    }
                    catch (Exception er )
                    {
                        MessageBox.Show(er.Message);
                    }
                    e.Accepted = isAccept;
                }
            }


    P.S. Другим предложениям или объяснением как лучше сделать буду только рад.
    Ответ написан
  • Как вылечить пользователя sa?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Если попытка соединения отклоняется в результате сбоя проверки подлинности из-за неправильного имени или пароля, клиенту выдается сообщение, подобное следующему: "Ошибка входа пользователя <имя_пользователя>.(Microsoft SQL Server, ошибка: 18456)".
    Более подробно и как искать причину описано здесь:MSDN
    Ответ написан
  • Нужно улучшить sql запрос.?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Список групп получайте вот так
    select 
          g.gid, 
          g.name
    from  groups g
    inner join  groupmembers gm ON gm.memberId = 1 AND g.gid = gm.groupId


    Количество подписчиков для каждой группы:
    select 
          g.name, 
       COUNT(gm.id) as CountGM
    from  groups g
    inner join  groupmembers gm ON gm.memberId = 1 AND g.gid = gm.groupId
    group by g.name

    И лучше уделите пару часов учебнику по SQL
    Ответ написан
    Комментировать
  • Как сделать выборку из БД делая объединение с разными таблицами в зависимости от значения поля?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Я думаю суть будет понятна - соединяем таблицы left join-ом и если значение в первом случае NULL то берем другое значение. Если типов сообщений будет больше чем 2, используйте оператор coalesce

    select 
    [ id пользователя]
     ISNULL(U.ID, system.id] as [ID сообщения]
     from tbl_notice  N
    left join user  U ON  U.ID=N.[id сообщения] and type="user"
    left join Systems  S ON  S.ID=N.[id сообщения] and type="System"


    P.S. Поздно увидел что вопрос для MYSQL, но для MS SQL работать будет точно.
    Ответ написан
    Комментировать
  • Что означает пометка зеленого цвета?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    По моему это подсветка изменений проекта после компиляции.
    Желтый - новый текст, еще не отлаженный. Зеленый - была сборка проекта.
    Ответ написан
    Комментировать
  • Как правильно написать sql-запрос?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    select 
     M.имя_маршрута
    ,G.имя_города 
    ,G2.имя_города
    from Маршруты M 
    inner join Города G ON  M.id_пункта_отправления=G.ID
    inner join Города G2  ON  M.id_пункта_назначения=G2.ID
    Ответ написан
    Комментировать
  • Можно ли в ComboBox добавить дополнительную информацию?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Для WinForms:
    Установите поставьте на DataSourse у ComboBox вашу таблицу. Затем в ValueMember укажите поле ID а в поле DisplayMember ваше поле Name.
    Вот тут можете посмотреть информацию как раз по вашему вопросу и по List и ComboBox
    metanit.com/sharp/windowsforms/4.8.php

    Если WPF используете, то там практически тоже самое
    Ответ написан
    Комментировать
  • Как быстро отсортировать и выбрать данные из 10000+ строк таблицы в C#?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Еще вариант на уровне MS SQL распарсить файл, сделать необходимы отбор и передать данные в приложение.
    Ниже даю пример парсинга xml-файла в таблицу. Попробуйте переделать под себя
    Взял кусок из рабочего примера, где использовались пространства имен в файле. Если у вас их нет - удалите
    declare @xdat xml 
    
    -- получаем xml-файл
    SET @xdat  = (SELECT [DataXml]  FROM [TaskXml]  where TaskDocGUID='1A91AED3-B5DF-4526-81E9-D54C16BB82A7')
    
    if object_id('TempDb..#AllDataTable') > 0 drop table #AllDataTable
    SELECT Product.ref.value('declare namespace pref="http://fsrar.ru/WEGAIS/ProductRef";  (pref:Type/text())[1]', 'nvarchar(50)') AS [Type]
    	,Product.ref.value('declare namespace   pref="http://fsrar.ru/WEGAIS/ProductRef";  (pref:FullName/text())[1]', 'nvarchar(255)') AS FullName
    	,Product.ref.value('declare namespace   pref="http://fsrar.ru/WEGAIS/ProductRef";  (pref:ShortName/text())[1]', 'nvarchar(64)') AS ShortName
    	,Product.ref.query('declare namespace   pref="http://fsrar.ru/WEGAIS/ProductRef";   pref:Producer[1]') AS Producer
    	,Producer.ref.value('declare namespace  oref="http://fsrar.ru/WEGAIS/ClientRef";   (oref:ClientRegId/text())[1]', 'nvarchar(50)') AS ClientRegIdProducer
    	,Producer.ref.value('declare namespace  oref="http://fsrar.ru/WEGAIS/ClientRef";   (oref:INN/text())[1]', 'nvarchar(255)') AS INNProducer
    INTO #AllDataTable
    FROM @xdat.nodes('declare namespace rap="http://fsrar.ru/WEGAIS/ReplyAP";
    				  declare namespace ns="http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01";
    				  /ns:Documents/ns:Document/ns:ReplyAP/rap:Products/rap:Product') AS Product(ref)
    CROSS APPLY Product.ref.nodes('declare namespace  pref="http://fsrar.ru/WEGAIS/ProductRef";  pref:Producer') AS Producer(ref)
    
     SELECT * FROM #AllDataTable


    Код выше трудно читаем и понимаем. Попробую дать пример попроще

    -- формируем докумет
    DECLARE @xdat XML = (
    		SELECT TOP 5 GUID
    			,StatusDoc
    		FROM V_EGAIS.dbo.ActChargeOnHeader
    		FOR XML path('List')
    			,ROOT('Document')
    			,ELEMENTS
    			,type
    		)
    
    -- ниже пример того что получилось
    --  <Document>
    --  <List>
    --    <GUID>7F705894-441F-4B59-B6C4-0003579AE9BA</GUID>
    --    <LDM>2016-02-04T15:58:01.650</LDM>
    --  </List>
    --  <List>
    --    <GUID>D6EADAEB-AD45-4EB9-962D-0003B82CB431</GUID>
    --    <LDM>2016-02-04T15:59:51.723</LDM>
    --  </List>
    --  <List>
    --    <GUID>84BA1332-7C1F-4BAB-9923-0003D4B2CD7A</GUID>
    --    <LDM>2016-02-04T15:58:57.443</LDM>
    --  </List>
    --  <List>
    --    <GUID>A56EF787-3549-43DD-99E8-00043ED70C11</GUID>
    --    <LDM>2016-02-04T15:56:59.223</LDM>
    --  </List>
    --  <List>
    --    <GUID>16939553-7927-4221-B260-00044EBC225F</GUID>
    --    <LDM>2016-02-04T15:57:29.297</LDM>
    --  </List>
    --</Document>
    -- теперь производим выборку
    SELECT Document.ref.value('(GUID/text())[1]', 'nvarchar(255)') AS [GUID]
    	     ,Document.ref.value('(StatusDoc/text())[1]', 'int') AS StatusDoc
    FROM @xdat.nodes('/Document/List') AS Document(ref) -- тут мы показываем с какого раздела можно начинать брать данные.
    Ответ написан
    3 комментария
  • Как заполнить документ excel средствами c#?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Если используете Microsoft.Office.Interop.Excel то что бы не было тормозов при заполнении передавайте данные сразу диапазоном. Вот один из моих методов, которыми пользуюсь.

    void ToExcel(DataTable dt1)
            {
                try
                {
                    Excel.Application EoXL;
                    Excel._Workbook EoWB;
                    Excel._Worksheet EoSheet;
                    Excel.Range excelRange;
                    EoXL = new Excel.Application();
                    EoXL.Visible = false;
                    EoWB = EoXL.Workbooks.Add(Type.Missing);
    
                    int TabRows = 1;
    
                    EoSheet = (Excel.Worksheet)EoWB.Worksheets.get_Item(1);//ссылка на лист excel
                    EoSheet.Name = "Отчет о кодах возвратных накладных";
                    EoSheet.PageSetup.Orientation = Excel.XlPageOrientation.xlLandscape;
    
                    int row = dt1.Rows.Count;
                    int col = dt1.Columns.Count;
    
    
                    EoSheet.Cells[1, 1] = "Префиксы возвратных накладных и счетов фактур подразделений";
                    EoSheet.Cells[1, 1].VerticalAlignment = Excel.XlVAlign.xlVAlignCenter;
                    EoSheet.Cells[1, 1].Font.Bold = true;
                    EoSheet.Cells[1, 1].Font.Size = 16;
    
                  
    
                    // передаем первую таблицу, заполняем ее в памяти и передаем целиком
                    object[,] dataExport = new object[row, col];
    
                    for (int i = 0; i < row; i++)
                    {
                        for (int j = 0; j < col; j++)
                        {
                            dataExport[i, j] = dt1.Rows[i][j];
                        }
    
                    }
    
    
                    excelRange = EoSheet.Range[EoSheet.Cells[2 + TabRows, 1], EoSheet.Cells[row + 1 + TabRows, col]];
                    excelRange.set_Value(Excel.XlRangeValueDataType.xlRangeValueDefault, dataExport);
                    excelRange.Borders.ColorIndex = 0;
    
    //этот кусок в качестве примера указания типа данных в ячейках
                    // excelRange = EoSheet.Range[EoSheet.Cells[2 + TabRows, 8], EoSheet.Cells[row + 1 + TabRows, 10]];
                    // excelRange.NumberFormat = "#,##0.00";
    
                    // формируем заголовок
                    ArrayList displayColumnExsel = new ArrayList();
    
    
                    foreach (DataColumn c in dt1.Columns)
                    {
    
                        displayColumnExsel.Add(c.ColumnName);
                    }
    
                    object[] dataExportH = new object[col];
                    for (int i = 0; i < col; i++)
                        dataExportH[i] = displayColumnExsel[i];
    
                    excelRange = EoSheet.Range[EoSheet.Cells[1 + TabRows, 1], EoSheet.Cells[1 + TabRows, col]];
                    excelRange.set_Value(Excel.XlRangeValueDataType.xlRangeValueDefault, dataExportH);
                    excelRange.Font.Bold = true;
                    excelRange.WrapText = true;
                    excelRange.Borders.ColorIndex = 0;
                    excelRange.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter;
                    excelRange.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
                          
    
                   EoXL.Visible = true;
                }
                catch (Exception er)
                {
                    MessageBox.Show(er.Message, "Ошибка метода переноса таблиц", MessageBoxButton.OK, MessageBoxImage.Error);
                }
    
    
            }
    Ответ написан
    5 комментариев
  • Xaml - Как динамически изменять содержимое окна (пример: главное окно -> настройки)?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Способов много.
    Вот несколько:
    1. Используйте MVVM пример
    2. Создание UserControl с содержимым и загрузка их в контейнер типа ContentPresenter
    3. Pages
    4. Шаблоны содержимого
    5. TabPages тоже можно заюзать на крайний случай. В WPF вкладки можно скрывать.
    Ответ написан
    Комментировать
  • Формула для Excel - как сделать минус всех значений?

    k1lex
    @k1lex
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    как вариант =-ABS(<адрес_ячейки>)
    Ответ написан
    Комментировать
  • Как организовать удаленную перезагрузку компьютеров с ОС MS-DOS?

    k1lex
    @k1lex Автор вопроса
    Программист торг. сети. C# (WPF, WinForms), T-SQL
    Решение нашел сам. На машинах стоит торговый модуль Кристалл, на котором имеется инструмент перезагрузки, но было неизвестно как он работает.
    В результате изучения его базы данных и анализа происходящего был написан запрос, который формирует задание на перезагрузку всех касс магазина:
    IF object_id('tempdb..#TableId') is not NULL DROP TABLE #TableId
    
    -- создаем временную таблицу с id-заданий на перезагрузку кассы
    SELECT tt.id as Targid
    INTO #TableId
    FROM [SES].[dbo].[TransferTargets] tt
    	INNER JOIN [SES].[dbo].[Cashes] cs
    On tt.Targetid = cs.number and tt.TargetType = 1
    
    -- заполнение таблицы заданий на ребут
    INSERT SES.dbo.TransferCmd 
       (TransferType, DataId, Operation, TargetId, Data, ContextId)
    SELECT 
       131, 0, 0, Targid, 'REBOOTCASH|TASK=0,1;QUEST=2', 0 
    FROM #TableId
    
    IF object_id('tempdb..#TableId') is not NULL DROP TABLE #TableId


    А дальше было добавлено задание, отрабатывающее по расписанию в необходимое мне время
    Ответ написан
    Комментировать