powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / Подключение к SQL
25 сообщений из 59, страница 2 из 3
Подключение к SQL
    #38378730
Фотография lbppb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mpkfaЗапрос напрямую из базы данных

Если не ошибаюсь, то GroupBy как раз вызывает подсчет строк. Попробуйте добавить SET NOCOUNT ON сразу после USE B2. Попробутей поэкспериментировать с созданием вида или хп, возможно Excel не проглатывает такую команду.
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378733
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lbppb,

Причем тут NOCOUNT и таймаут??? Если была бы проблема с NOCOUNT, была бы ошибка про BOF/EOF, а у автора ошибка "Таймаут". 45 сек как раз таймаут по умолчанию.
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378742
mpkfa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lbppb, не сработало(
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378747
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mpkfa,

точно таймаут? какой текст ошибки?
Приведите фрагмент кода, как программируете таймаут и выполняете запрос?
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378764
mpkfa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,
Код: vbnet
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.
Private Sub Pusk_Click()
Query
Dim oCn As ADODB.Connection
Dim oRs As ADODB.Recordset
Dim oCmd As ADODB.Command
Dim sCn As String
Dim sSql As String
Dim sRng As String

Set oCn = New ADODB.Connection
Set oRs = New ADODB.Recordset
Set oCmd = New ADODB.Command

oCn.ConnectionTimeout = 0
oCn.CommandTimeout = 0
oCmd.CommandTimeout = 0

sCn = "Provider=SQLOLEDB.1;Password=123;Persist Security Info=True;User ID=fg;Initial Catalog=B2;Data Source=MARKET6\M6" 'Your connection string
oCn.Open sCn

sSql = S '"select top 100 * from B2.dbo.T1" 'Your query

oCmd.CommandType = adCmdText
oCmd.CommandText = sSql
oCmd.ActiveConnection = oCn

Set oRs = oCmd.Execute

sRng = "A:AA"
ActiveSheet.Range(sRng).Clear
PutRecordsetInSheet oRs, ActiveSheet.Range("A1"), True

oRs.Close
oCn.Close
Set oCmd = Nothing
Set oRs = Nothing
Set oCn = Nothing

End Sub



Private Sub PutRecordsetInSheet(ByVal RS As Recordset, ByVal TopLeft As Range, Optional ByVal Headers As Boolean = True)
    Dim objField As ADODB.Field
    Dim i As Integer
    If Headers Then
        For Each objField In RS.Fields
            i = i + 1
            TopLeft.Cells(1, i).Value = objField.Name
        Next objField
        TopLeft.Cells(2, 1).CopyFromRecordset RS
    Else
        TopLeft.Cells(1, 1).CopyFromRecordset RS
    End If
End Sub



Дебуггер выделяет строчку TopLeft.Cells(2, 1).CopyFromRecordset RS
а ошибка run-time error '3704' Операция не допускается если объект закрыт.
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378770
mpkfa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
функция query формирует текст запроса аналогичного представленному выше(уже был пример текста запрос)
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378772
mpkfa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378798
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и где тут, спрашивается, таймаут????

Почему у вас рекордсет передается ByVal? Естественно он закрыт, а чего еще ожидать?
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378812
mpkfa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro, а покажите как надо?)) просто убрать byVal?
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378825
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mpkfaShocker.Pro, а покажите как надо?)) просто убрать byVal?Надо просто открыть хелп и прочитать, что такое ByVal, вы же это сами придумали написать, а не где-то скопировали.
Должно быть ByRef

mpkfaгде то тайм аут выходит а где не понятно.mpkfaЕсть мысль что Connection и recordset живут независимо друг от друга...mpkfaа он рекордсет закрывает.на будущее - не надо никаких домыслов, сразу пишите конкретный код и конкретную ошибку, это решило бы вопрос с первого же ответа
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378873
mpkfa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне кажется byval тут ни при чем. С простым запросом то все работает. И recordset нормально данные передает. Когда же запрос выполняется больше 45 сек тогда ошибку выдает.
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378876
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
C простым запросом работает именно этот код?
On Error Resume Next используется?
Option Explicit используется?
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378882
mpkfa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro, Да, именно этот код. Option explicit стоит самой первой строчкой. On Error Resume Next не использовал. А куда поставить?
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378895
mpkfa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro, вот весь код.
Код: vbnet
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.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
Option Explicit
Public S, U1, N1, N2 As String

Private Sub ComboBox1_Change()
If ComboBox1.Value = 12 Then
                              U1 = " WHERE t.god = 12"
                        Else: U1 = " WHERE t.god = 13"
End If
End Sub


Private Sub ComboBox2_Change()
If ComboBox2.Value = 1 Then
                              U1 = U1 & " AND t.mes = 1"
 ElseIf ComboBox2.Value = 2 Then U1 = U1 & " AND t.mes = 2"
 ElseIf ComboBox2.Value = 3 Then U1 = U1 & " AND t.mes = 3"
 ElseIf ComboBox2.Value = 4 Then U1 = U1 & " AND t.mes = 4"
 ElseIf ComboBox2.Value = 5 Then U1 = U1 & " AND t.mes = 5"
 ElseIf ComboBox2.Value = 6 Then U1 = U1 & " AND t.mes = 6"
 ElseIf ComboBox2.Value = 7 Then U1 = U1 & " AND t.mes = 7"
 ElseIf ComboBox2.Value = 8 Then U1 = U1 & " AND t.mes = 8"
 ElseIf ComboBox2.Value = 9 Then U1 = U1 & " AND t.mes = 9"
 ElseIf ComboBox2.Value = 10 Then U1 = U1 & " AND t.mes = 10"
 ElseIf ComboBox2.Value = 11 Then U1 = U1 & " AND t.mes = 11"
 ElseIf ComboBox2.Value = 12 Then U1 = U1 & " AND t.mes = 12"
 End If
End Sub

Private Sub Query()


Dim S1, S2, S3, S4, S5, S6, S7, S31 As String
S1 = " Use B2 SELECT top 5 max(g1.akb_v_obl1) as 'akb1', g1.offtake1,g1.procentakb1, g1.kl1,"
N1 = " t.obl,"
S2 = " t.god FROM B2.dbo.T1 t Left Join( SELECT sum(t.kg) / count(distinct t.kodKl) as 'offtake1', vsekg.klobl1 as 'akb_v_obl1',100 * count(distinct t.kodKl) / vsekg.klobl1 as 'procentakb1', count(distinct t.kodKl) as 'kl1',"
S3 = " t.god FROM B2.dbo.T1 t join (SELECT count(distinct t.kodKl) as 'klobl1',t.obl FROM B2.dbo.T1 t "
S31 = " Group By t.obl ) AS vsekg on vsekg.obl = t.obl"
S4 = " Group By vsekg.klobl1,"
S5 = " t.god ) AS g1 on     g1.god = t.god"
N2 = " AND g1.obl = t.obl "
S6 = " GROUP BY  g1.offtake1,g1.procentakb1, g1.kl1,"
S7 = " t.god"

    If CheckBox1.Value = True Then

                              N1 = N1 & " t.kategory,"
                              N2 = N2 & " AND g1.kategory = t.kategory"
    End If

    If CheckBox2.Value = True Then
                          N1 = N1 & " t.GrKl,"
                          N2 = N2 & " AND g1.Grkl = t.Grkl"
    End If

    If CheckBox3.Value = True Then
                          N1 = N1 & " t.TipT,"
                          N2 = N2 & " AND g1.TipT = t.TipT"
    End If

    If CheckBox4.Value = True Then
                          N1 = N1 & " t.FormT,"
                          N2 = N2 & " AND g1.FormT = t.FormT"
    End If

    If CheckBox5.Value = True Then
                          N1 = N1 & " t.Brand,"
                          N2 = N2 & " AND g1.Brand = t.Brand"
    End If

    If CheckBox6.Value = True Then
                          N1 = N1 & " t.sku,"
                          N2 = N2 & " AND g1.sku = t.sku"
    End If
S = S1 + N1 + S2 + N1 + S3 + U1 + S31 + U1 + S4 + N1 + S5 + N2 + U1 + S6 + N1 + S7



End Sub



Private Sub OptionButton1_Click()


End Sub



Private Sub Pusk_Click()
Query
Dim oCn As ADODB.Connection
Dim oRs As ADODB.Recordset
Dim oCmd As ADODB.Command
Dim sCn As String
Dim sSql As String
Dim sRng As String

Set oCn = New ADODB.Connection
Set oRs = New ADODB.Recordset
Set oCmd = New ADODB.Command

oCn.ConnectionTimeout = 0
oCn.CommandTimeout = 0
oCmd.CommandTimeout = 0

sCn = "Provider=SQLOLEDB.1;Password=123;Persist Security Info=True;User ID=fg;Initial Catalog=B2;Data Source=MARKET6\M6" 'Your connection string
oCn.Open sCn

sSql = S '"select top 100 * from B2.dbo.T1" 'Your query

oCmd.CommandType = adCmdText
oCmd.CommandText = sSql
oCmd.ActiveConnection = oCn

Set oRs = oCmd.Execute

sRng = "A:AA"
ActiveSheet.Range(sRng).Clear
PutRecordsetInSheet oRs, ActiveSheet.Range("A1"), True

oRs.Close
oCn.Close
Set oCmd = Nothing
Set oRs = Nothing
Set oCn = Nothing

End Sub



Private Sub PutRecordsetInSheet(RS As Recordset, TopLeft As Range, Optional Headers As Boolean)
    Dim objField As ADODB.Field
    Dim i As Integer
    If Headers Then
        For Each objField In RS.Fields
            i = i + 1
            TopLeft.Cells(1, i).Value = objField.Name
            Next objField
        TopLeft.Cells(2, 1).CopyFromRecordset RS
    Else
        TopLeft.Cells(1, 1).CopyFromRecordset RS
    End If
End Sub



если я в строке sSql = S '"select top 100 * from B2.dbo.T1" 'Your query оставляю строку запроса S то выдает ошибку, а если запрос из коммента, то работает. Причем напрямую в среде sql запрос S работает и выполняется около 2,5 мин.
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378897
Фотография lbppb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Prolbppb,

Причем тут NOCOUNT и таймаут??? Если была бы проблема с NOCOUNT, была бы ошибка про BOF/EOF, а у автора ошибка "Таймаут". 45 сек как раз таймаут по умолчанию.

У меня была точно такая же ошибка и проблема была как раз в NOCOUNT, и не у одного меня:
http://stackoverflow.com/questions/7663617/adodb-open-recordset-fails-operation-is-not-allowed-when-object-is-closed
http://www.vbforums.com/showthread.php?569433-VBA-Excel-error-3704-operation-is-not-allowed-when-the-object-is-closed

Все дело в том, что когда NOCOUNT OFF, то данные с сервера возвращаются со счетчиком записей и VBA с этим уже не может справиться. При чем запрос исполняется себе и в самом конце, когда данные должны вернуться вылезает ошибка. По симптомам очень даже похоже на случай ТС.
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378905
Фотография lbppb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProНу и где тут, спрашивается, таймаут????

Почему у вас рекордсет передается ByVal? Естественно он закрыт, а чего еще ожидать?

ByVal тут абсолютно ни при чем. Вы наверное с чем-то путаете или код не внимательно посмотрели.
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378924
mpkfa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lbppb, вот такой
Код: plsql
1.
2.
3.
select top 100 t.god,count(distinct t.kodkl)
 from B2.dbo.T1 t
 group by t.god



запрос тоже работает. Выполняется за 19 сек и выдает все нормально. Значит и не в group by дело... Где то таймер спрятался...
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378945
Фотография lbppb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mpkfa,

Какая версия Excel и сколько строк должно возвращаться с запроса?
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378959
mpkfa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lbppb, эксель 2007, а строк должно вернуться не более 10 тыс. Просто там много вычисляемых в агрегатных функциях величин, поэтому делается долго. Думаю ограничения по строкам думаю тут ни при чем. А на драйвере подключения не может быть этого оганичения?
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378976
Фотография lbppb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mpkfalbppb, эксель 2007, а строк должно вернуться не более 10 тыс. Просто там много вычисляемых в агрегатных функциях величин, поэтому делается долго. Думаю ограничения по строкам думаю тут ни при чем. А на драйвере подключения не может быть этого оганичения?

Я протестировал, у меня сотни тысяч строк возвращаются и занимает где-то 5 минут. Я не знаю, может у вас на сервере стоит ограничение, но тогда не понятно как у вас раньше работало.

Попробуйте тот же самый текст запроса на сервере и вручную в Excel.
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378977
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Небольшое отвлечение
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Private Sub ComboBox2_Change()
If ComboBox2.Value = 1 Then
                              U1 = U1 & " AND t.mes = 1"
 ElseIf ComboBox2.Value = 2 Then U1 = U1 & " AND t.mes = 2"
 ElseIf ComboBox2.Value = 3 Then U1 = U1 & " AND t.mes = 3"
 ElseIf ComboBox2.Value = 4 Then U1 = U1 & " AND t.mes = 4"
 ElseIf ComboBox2.Value = 5 Then U1 = U1 & " AND t.mes = 5"
 ElseIf ComboBox2.Value = 6 Then U1 = U1 & " AND t.mes = 6"
 ElseIf ComboBox2.Value = 7 Then U1 = U1 & " AND t.mes = 7"
 ElseIf ComboBox2.Value = 8 Then U1 = U1 & " AND t.mes = 8"
 ElseIf ComboBox2.Value = 9 Then U1 = U1 & " AND t.mes = 9"
 ElseIf ComboBox2.Value = 10 Then U1 = U1 & " AND t.mes = 10"
 ElseIf ComboBox2.Value = 11 Then U1 = U1 & " AND t.mes = 11"
 ElseIf ComboBox2.Value = 12 Then U1 = U1 & " AND t.mes = 12"
 End If
End Sub

А если у вас будет 1000 возможных значений, вы 1000 раз напишете ElseIf?

Код: vbnet
1.
2.
3.
Private Sub ComboBox2_Change()
   U1 = U1 & " AND t.mes = "+CStr(ComboBox2.Value)
End Sub

...
Рейтинг: 0 / 0
Подключение к SQL
    #38378982
f
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуй в папке с ado (у меня это C:\Program Files\Common Files\System\ado\) при помощи
regsvr32 зарегистрировать из командной строки все файлы dll.

Например: regsvr32 "C:\Program Files\Common Files\System\ado\msado15.dll"
Или создай батник.

Иногда помогает.
...
Рейтинг: 0 / 0
Подключение к SQL
    #38378984
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для тестов таймаута можно просто выполнить:
Код: sql
1.
waitfor delay '00:01:00' select 5

запрос подождет минуту потом вернет одну строку, так будет понятно, в запросе и количестве строк дело или в таймауте
...
Рейтинг: 0 / 0
Подключение к SQL
    #38379001
mpkfa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем спасибо за помощь. Завтра продолжу. Приходите еще)))
...
Рейтинг: 0 / 0
Подключение к SQL
    #38379122
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lbppb,

Я не прав, прошу прощения, отсутствие NOCOUNT действительно приведет к такой ошибке, а не к BOF/EOF

Правда автор говорит, что "не сработало", но может все-таки не туда или не так вставил.

Для проверки этой ситуации можно после
Код: vbnet
1.
Set oRs = oCmd.Execute

вставить
Код: vbnet
1.
Set oRs = oRs.NextRecordset
...
Рейтинг: 0 / 0
25 сообщений из 59, страница 2 из 3
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / Подключение к SQL
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]