Форум программистов, компьютерный форум, киберфорум
Наши страницы
Visual Basic .NET
Войти
Регистрация
Восстановить пароль
 
Andrey_Kaptyg
3 / 3 / 1
Регистрация: 15.06.2017
Сообщений: 12
#1

Оптимизировать код обработки данных Access - Visual Basic .NET

15.10.2017, 17:33. Просмотров 213. Ответов 9
Метки нет (Все метки)

Всем доброго дня!
Подскажите как оптимизировать (ускорить обработку) данных хранящихся в таблицах Access.

Есть 2 таблицы - [Данные сотрудников] и [Инструктажи сотрудников].
В [Инструктажи сотрудников] хранятся хранятся данные о всех инструктажах Сотрудников (их у сотрудника может быть МНОГО).
Код из [Данные сотрудников] привязан к Номеру сотрудника в [Инструктажи сотрудников]

Процедура работает - не хотелось бы максимально ускорить .

Скорее всего можно как-то составить SQL запрос.... Но я не знаю как...

Вот сам код процедуры:


vb.net
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
 Private Sub Podschet() ' Процедура получения количества просроченных инструктажей
        ' Процедура получения количества просроченных инструктажей
        KolInsr = 0 ' Задаем количество просроченных инструктажей равным 0
 
        'Заполняем таблицу сотрудниками
        DT6.Clear() 'Очищаем таблицу
        SqlCom = New OleDb.OleDbCommand("SELECT * FROM [Данные сотрудников] ORDER BY [Фамилия]", Con) ' Указываем строку запроса и привязываем к соединению
        Con.Open() ' Открываем соединение
        SqlCom.ExecuteNonQuery() 'Выполняем запрос
        DA = New OleDb.OleDbDataAdapter(SqlCom) 'Через адаптер получаем результаты запроса
        DA.Fill(DT6) ' Заполняем таблицу результатми
        Con.Close()
        ' __________________________________________________________________________________
 
 
        Dim KolStrok As Integer = DT6.Rows.Count 'находим число строк в таблице DT6
 
        Dim SotrMass(KolStrok + 1, 2)  ' Объявляем массив для данных
        Dim n As Integer = 0 ' счетчик строк таблицы DT6
 
        Dim y As Integer = 0
       
        For stroka = 1 To KolStrok
            Dim qqq = DT6.Rows.Item(n)
            
            'Заполняем таблицу проведенными Инструктажами
            DT15.Clear() 'Очищаем таблицу
            
            SqlCom = New OleDb.OleDbCommand("SELECT * FROM [Инструктажи сотрудников] WHERE ([Номер сотрудника]=" & qqq.ItemArray(0).ToString & ") ORDER BY [Дата проведения]", Con) ' Указываем строку запроса и привязываем к соединению
            Con.Open() ' Открываем соединение
            SqlCom.ExecuteNonQuery() 'Выполняем запрос
            DA = New OleDb.OleDbDataAdapter(SqlCom) 'Через адаптер получаем результаты запроса
            DA.Fill(DT15) ' Заполняем таблицу результатми
            Con.Close() ' Закрываем соединение
            
            Dim KolStrok2 As Integer = DT15.Rows.Count 'находим число строк в таблице DT15
 
            If KolStrok2 = 0 Then ' Заменить на DT15.Rows.Count
                KolInsr = KolInsr + 1
            Else
                Dim qqq1 = DT15.Rows.Item(DT15.Rows.Count - 1)
                Dim dat2 As Date = CDate(qqq1.ItemArray(3).ToString) 'Получаем дату последнего инструктажа
                Dim dat3 As Date ' Дата следующего инструктажа
                '_________________________________________________
 
                If qqq1.ItemArray(4).ToString = "" Then
                    'Если интервал прохождения не задан то по умолчанию ставим 3 месяца
                    dat3 = DateAdd("m", 3, CDate(qqq1.ItemArray(3).ToString))
 
                Else
                    'Находим дату следующего инструктажа
                    dat3 = DateAdd("m", CInt(qqq1.ItemArray(4).ToString), CDate(qqq1.ItemArray(3).ToString))
                    'qqq1.ItemArray(4).ToString - здесь берем интервал следующего инструктажа
                End If
 
 
 
                Dim nnn As Long = DateDiff(DateInterval.Day, dat3, Now)
 
                If nnn > 0 Then 'Если промежуток больше 0 дней от 
                    KolInsr = KolInsr + 1 'прибавляем к колличеству 1
                    y = y + 1
 
                Else
 
                End If
 
            End If
 
            n = n + 1
 
        Next
 
        Label1.Text = "Просрочено инструктажей : " & "" & KolInsr
        Label2.Text = "Всего сотрудников : " & "" & CStr(KolStrok)
        If KolInsr = 0 Then
            Label1.ForeColor = Color.Green
            Label1.Text = "Просроченных инструктажей нет "
        End If
 
 
 
    End Sub
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.10.2017, 17:33
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Оптимизировать код обработки данных Access (Visual Basic .NET):

Оптимизировать и улучшить код калькулятора
Помогите довести Калькулятор до идеала:( а то я первый раз пишу и спросить не у...

Оптимизировать код, содержащий вложенные циклы
Вот код : Dim a As Long Do a += 1 ...

Исходник заставки vb.net 2008. Стоит ли оптимизировать код?
Добрый день. Господа есть исходник заставки которая полностью работает но...

Как оптимизировать код поиска слов и их выделения цветом в RichTextBox
Написал код поиска слов и их выделения цветом в RichTextBox: ...

какой формат базы данных DSN Access (атрибуты и типы данных) ?
В настройках IIS можно выбирать формат журнала, один из форматов - это DSN...

Логистика класса или лучший способ обработки данных
Добрый день, Товарищи! Я в общем то представляю различные типы массивов и т.д....

9
ovva
2203 / 1907 / 472
Регистрация: 02.02.2013
Сообщений: 1,782
Записей в блоге: 2
16.10.2017, 18:46 #2
Лучший ответ Сообщение было отмечено Andrey_Kaptyg как решение

Решение

Andrey_Kaptyg,
Наверное, имеет смысл объединить две выборки в одну.
Кликните здесь для просмотра всего текста
vb.net
1
2
3
4
5
6
7
8
9
10
11
12
13
Dim tb As New DataTable()
Dim connString As String = "Provider = Microsoft.Jet.OLEDB.4.0; Data Source = " & IO.Path.Combine(Application.StartupPath, "training.mdb") & "; Password=;"
Using conn = New OleDbConnection(connString)
    conn.Open()
    Dim cmdText As String = "SELECT employee.Name, instruction.Name, instruction.insDate FROM employee INNER JOIN instruction ON employee.ID=instruction.empID"
    Dim cmd As OleDbCommand = New OleDbCommand(cmdText, conn)
    Try
        Dim da As OleDbDataAdapter = New OleDbDataAdapter(cmd)
        da.Fill(tb)
    Catch ex As OleDbException
        MsgBox(ex.Message)
    End Try
End Using

Здесь речь идет о таблицах:
employee (ID; Name)
instruction (ID; Name; empID; insDate [as Date])
Число записей в таблице employee можно определить так
Кликните здесь для просмотра всего текста
vb.net
1
2
3
4
5
6
7
8
9
10
Using conn = New OleDbConnection(connString)
    conn.Open()
    Dim cmdText As String = "SELECT count(*) FROM employee"
    Dim cmd As OleDbCommand = New OleDbCommand(cmdText, conn)
    Try
        eCount = cmd.ExecuteScalar
    Catch ex As OleDbException
        MsgBox(ex.Message)
    End Try
End Using
2
Andrey_Kaptyg
3 / 3 / 1
Регистрация: 15.06.2017
Сообщений: 12
16.10.2017, 19:59  [ТС] #3
Спасибо за предложенный вариант!

Я не сильный знаток SQL, но думаю нужно идти другим путем...

В таблице [Данные сотрудников] у каждого сотрудника есть свой уникальный КОД
В таблице [Инструктажи сотрудников] к данному КОД привязаны все инструктажи для данного сотрудника.
То есть - у сотрудника с КОД=137, в таблице [Инструктажи сотрудников] имеется допустим 10 записанных инструктажей с разными датами и полем [НОМЕР СОТРУДНИКА]=137.

Так вот у меня задача : Составить SQL запрос который для каждой записи из таблицы [Данные сотрудников] по КОД который равен [НОМЕР СОТРУДНИКА] выберет из таблицы [Инструктажи сотрудников] инструктаж с самой последней датой.

Пока остановился на запросе (и он работает) на выборку максимальной ДАТЫ из таблицы [Инструктажи сотрудников] по КОД.
Вот:
vb.net
1
SqlCom = New OleDb.OleDbCommand("SELECT MAX([Дата проведения]) FROM [Инструктажи сотрудников] WHERE [Номер сотрудника]=" & 137 & " ", Con)
0
ovva
2203 / 1907 / 472
Регистрация: 02.02.2013
Сообщений: 1,782
Записей в блоге: 2
16.10.2017, 20:45 #4
Лучший ответ Сообщение было отмечено Andrey_Kaptyg как решение

Решение

В приведенном мной коде полученная выборка записывается в таблицу, при этом вы только один раз обращаетесь к базе данных. С полученной таблицей можно выполнять различные операции, например
vb.net
1
2
3
4
'выбрать все записи по имени сотрудника nm
Dim row() As DataRow = tb.Select("employee.Name=" & Chr(39) & nm & Chr(39))
'выбрать все записи в интервале дат [dat1, dat2]
Dim rw() As DataRow = (From r As DataRow In tb.Rows Where r!insDate >= dat1 AndAlso r!insDate <= dat2).ToArray
Или же, как вы планировали, выборка записи по максимальной дате для конкретного пользователя (nm).
vb.net
1
2
Dim rw() As DataRow = tb.Select("employee.Name=" & Chr(39) & nm & Chr(39), "insDate DESC")
Dim maxDataRow As DataRow = rw(0)
Если вам удобнее использовать идентификаторы, то нужно включить в список полей (в объединенном запросе) employee.ID.
Естественно все это вы должны переложить на свою базу данных (таблицы, поля), но не думаю что это слишком сложно.
0
Andrey_Kaptyg
3 / 3 / 1
Регистрация: 15.06.2017
Сообщений: 12
16.10.2017, 22:27  [ТС] #5
Спасибо!!!!

Буду пробовать Ваш код.

Я со своим - что то зашел в тупик...
0
Andrey_Kaptyg
3 / 3 / 1
Регистрация: 15.06.2017
Сообщений: 12
16.10.2017, 23:49  [ТС] #6
ovva: Еще раз БОЛЬШОЕ спасибо!!!

Запрос отлично все выбирает, ну а дальше - работа с таблицами...
0
Миниатюры
Оптимизировать код обработки данных Access  
ovva
2203 / 1907 / 472
Регистрация: 02.02.2013
Сообщений: 1,782
Записей в блоге: 2
17.10.2017, 20:55 #7
Andrey_Kaptyg, возможно будет полезно:
Удобно в таблице-выборке иметь короткие имена полей, например имя employee.Name заменить на имя emName. Это можно сделать так
vb.net
1
Dim cmdText As String = "SELECT employee.Name as [emName], instruction.Name as [inName], instruction.insDate FROM employee INNER JOIN instruction ON employee.ID=instruction.empID"
Для вашего случая
vb.net
1
2
3
4
5
6
7
8
'сформировать список имен сотрудников (вместо обращения к базе данных)
Dim row = ((From r As DataRow In tb.Rows Select r!emName).ToArray).Distinct
'всего сотрудников
Dim emCount As Integer = row.Count
'проходим по всем сотрудникам
For Each rw As String In row
    '... некоторая операция для каждого сотрудника
Next
2
Andrey_Kaptyg
3 / 3 / 1
Регистрация: 15.06.2017
Сообщений: 12
17.10.2017, 22:28  [ТС] #8
ovva, На счет коротких имен полей таблиц я знал. Но в моем случае в Базе слишком много полей и таблиц, так что можно запутаться.
Поэтому решил работать с длинными названиями таблиц и полей и на русском языке.
По Вашему коду у меня получился вот такой запрос который работает:

vb.net
1
 SqlCom = New OleDb.OleDbCommand("SELECT [Данные сотрудников].Код, [Данные сотрудников].[Фамилия], [Инструктажи сотрудников].[Вид инструктажа], [Инструктажи сотрудников].[Дата проведения] FROM [Данные сотрудников] INNER JOIN [Инструктажи сотрудников] ON [Данные сотрудников].Код = [Инструктажи сотрудников].[Номер сотрудника] ", Con)
Методом "научного тыка" понял , что поля и таблицы состоящие из нескольких слов - нужно обязательно брать в скобки. Если это одно слово - то не обязательно.

На счет "SELECT employee.Name as [emName].......... то это работает и в моем случае....пробовал.

Например "SELECT [Данные сотрудников].Код AS Number........ просто изменит название поля выбранных данных на Number.
0
ovva
2203 / 1907 / 472
Регистрация: 02.02.2013
Сообщений: 1,782
Записей в блоге: 2
17.10.2017, 23:19 #9
Цитата Сообщение от Andrey_Kaptyg Посмотреть сообщение
Методом "научного тыка" понял , что поля и таблицы состоящие из нескольких слов - нужно обязательно брать в скобки.
Не только в этом случае, но и при использовании зарезервированных слов, например
vb.net
1
SELECT employee.Name as Date, …
в конечном счете, приведет к прерыванию, а
vb.net
1
SELECT employee.Name as [Date], …
позволит получить нужный результат.
3
Andrey_Kaptyg
3 / 3 / 1
Регистрация: 15.06.2017
Сообщений: 12
18.10.2017, 07:12  [ТС] #10
Согласен.
0
18.10.2017, 07:12
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.10.2017, 07:12
Привет! Вот еще темы с решениями:

Вывод данных из базы данных access в TextBox
На форме допустим 10 текстбоксов, в них надо вывести данные из записи таблицы...

Дабавление данных из файла в базу данных Access
Здравствуйте! При передаче данных из файла tpo1.txt в базу данных sst.mdb...

Код для поиска в БД Access
vb.net как писать код поиск на акцес

Адаптация запроса Access для вставки в код VS
В Access'е есть таблица и готовый запрос: PARAMETERS N Long; SELECT Событие,...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru