:: Не фоксом единым
EXCEL В OLEDB;Provider=VFPOLEDB.1 ИЗМЕНИТЬ ПРОГРАММНО СВОЙСТВО CommandText
LUCIAN
Автор

Сообщений: 343
Откуда: Лида Беларусь
Дата регистрации: 25.03.2008
Как переписать правильно такой код
Private Sub CommandButton1_Click()
With ActiveSheet.ListObjects.Add(SourceType:=0, Source:=Array( _
"OLEDB;Provider=VFPOLEDB.1;Data Source=F:\SBT\TTN\TTN.DBC;Mode=Share Deny None;Extended Properties="""";User ID="""";Mask Password=False;Ca" _
, _
"che Authentication=False;Encrypt Password=False;Collating Sequence=RUSSIAN;DSN="""";DELETED=True;CODEPAGE=1251;MVCOUNT=16384;ENGIN" _
, _
"EBEHAVIOR=90;TABLEVALIDATE=3;REFRESH=5;VARCHARMAPPING=False;ANSI=True;REPROCESS=5" _
), Destination:=Range("$I$1")).QueryTable
.CommandType = xlCmdSql
.CommandText = Array( _
"SELECT Sp_prd.kp, Sp_prd.namp, Sp_prd.ed_izm, SUM(Ttnd.kol*(2*ttn.op-1)) kol, SUM(Ttnd.suman*(2*ttn.op-1)) suman, S" _
, _
"UM(Ttnd.snds*(2*ttn.op-1)) snds,SUM(Ttnd.suma*(2*ttn.op-1)) suma, NVL(kurs.kurs,1.00000) kurs, Ttnd.id_prd FROM tt" _
, _
"n!ttn LEFT JOIN TTN!KURS ON DTOS(Kurs.data)+Kurs.val = DTOS(Ttn.dato)+Ttn.val INNER JOIN ttn!ttnd ON Ttnd.id_ttn " _
, _
"= ttn.id_ttn INNER JOIN ttn!sp_prd ON Sp_prd.id_prd = Ttnd.id_prd WHERE Ttn.dato BETWEEN {^2017-06-01} AND {^2017" _
, _
"-06-30}
AND Sp_prd.prp = '1' AND ' ' $ UPPER(Sp_prd.namp) AND Sp_prd.kp BETWEEN 0 AND 99999999 GROUP BY Sp_prd.kp," _
, " Ttnd.id_prd,Sp_prd.namp, Sp_prd.ed_izm,8")
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = True
.SourceConnectionFile = _
"C:\Documents and Settings\PETR1\Мои документы\Мои источники данных\OTGR_PR.odc"
.ListObject.DisplayName = "Таблица_OTGR_PR"
.Refresh BackgroundQuery:=False
End With
End Sub

потому что,если выделенный текст заменить на такой
...Ttn.dato BETWEEN "_TextBox1.Text_" AND "_TextBox2.Text, то выдаёт ошибку компиляции,
где TextBox1 и TextBox2 это TextBox куда будут вводится даты периода.
Ratings: 0 negative/0 positive
Re: EXCEL В OLEDB;Provider=VFPOLEDB.1 ИЗМЕНИТЬ ПРОГРАММНО СВОЙСТВО CommandText
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Использовать параметры.
.CommandText = "... WHERE Ttn.dato BETWEEN ? AND ?"
Set param1 = .Parameters.Add("From_date", xlParamTypeDate)
param1.SetParam xlConstant, #1/1/2015#
Set param2 = .Parameters.Add("To_date", xlParamTypeDate)
param2.SetParam xlConstant, #1/1/2016#
...
Как/откуда взять значение типа даты чтобы подсунуть в вызов метода param1.SetParam это уж тебе виднее - выше просто константы прописаны. Можно ссылку на ячейку поставить (но там должна быть дата, или число которое эксель может превратить в корректную дату).


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: EXCEL В OLEDB;Provider=VFPOLEDB.1 ИЗМЕНИТЬ ПРОГРАММНО СВОЙСТВО CommandText
LUCIAN
Автор

Сообщений: 343
Откуда: Лида Беларусь
Дата регистрации: 25.03.2008
Igor Korolyov
Использовать параметры.
"= ttn.id_ttn INNER JOIN ttn!sp_prd ON Sp_prd.id_prd = Ttnd.id_prd WHERE Ttn.dato BETWEEN ? AND ?" _
, _
" AND Sp_prd.prp = '1' AND ' ' $ UPPER(Sp_prd.namp) AND Sp_prd.kp BETWEEN 0 AND 99999999 GROUP BY Sp_prd.kp," _
, " Ttnd.id_prd,Sp_prd.namp, Sp_prd.ed_izm,8")
Set param1 = .Parameters.Add("From_date", xlParamTypeDate)
param1.SetParam xlConstant, #1/1/2017#
Set param2 = .Parameters.Add("To_date", xlParamTypeDate)
param2.SetParam xlConstant, #31/1/2017#
При таком использовании параметров получаю ошибку:

Application-defined or object-defined error



Исправлено 1 раз(а). Последнее : LUCIAN, 26.07.17 16:52
Ratings: 0 negative/0 positive
Re: EXCEL В OLEDB;Provider=VFPOLEDB.1 ИЗМЕНИТЬ ПРОГРАММНО СВОЙСТВО CommandText
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Цитата:
You must enclose a Date literal within number signs (# #). You must specify the date value in the format M/d/yyyy, for example #5/31/1993#, or yyyy-MM-dd, for example #1993-5-31#. You can use slashes when specifying the year first. This requirement is independent of your locale and your computer's date and time format settings.
Не бывает 31 месяца.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: EXCEL В OLEDB;Provider=VFPOLEDB.1 ИЗМЕНИТЬ ПРОГРАММНО СВОЙСТВО CommandText
LUCIAN
Автор

Сообщений: 343
Откуда: Лида Беларусь
Дата регистрации: 25.03.2008
Igor Korolyov
Не бывает 31 месяца.
И такой записи:
param2.SetParam xlConstant, #1/31/2017#
получаю ту же ошибку:
Application-defined or object-defined error
Ratings: 0 negative/0 positive
Re: EXCEL В OLEDB;Provider=VFPOLEDB.1 ИЗМЕНИТЬ ПРОГРАММНО СВОЙСТВО CommandText
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Ну не знаю, я проверить не могу, т.к. эксель у меня 64-разрядный. А из фокса через ADODB.Command с тестовой таблицей с полем Date всё работает. Конечно там чуть иной синтаксис, да и строка подключения без кучи чисто экселевских параметров. Но всё работает
Пошагово попробуй исполнить, посмотри до куда дойдёт. Посмотри потом уже в экселевском (не VBA) интерфейсе свойства этого диапазона данных (там видна и строка подключения, и запрос, и параметры).


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: EXCEL В OLEDB;Provider=VFPOLEDB.1 ИЗМЕНИТЬ ПРОГРАММНО СВОЙСТВО CommandText
LUCIAN
Автор

Сообщений: 343
Откуда: Лида Беларусь
Дата регистрации: 25.03.2008
Запрос с таким текстом
.CommandText = Array( _
"SELECT Sp_prd.kp, Sp_prd.namp from ttn!sp_prd where kp in (?,?) ")
Set param1 = .Parameters.Add("kp1", xlParamTypeDecimal)
param1.SetParam xlConstant, 7410
Set param2 = .Parameters.Add("kp2", xlParamTypeDecimal)
param2.SetParam xlConstant, 8230
не работает,а запрос с таким текстом

.CommandText = Array( _
"SELECT Sp_prd.kp, Sp_prd.namp from ttn!sp_prd where kp in (7410,8230) ")
Set param1 = .Parameters.Add("kp1", xlParamTypeDecimal)
param1.SetParam xlConstant, 7410
Set param2 = .Parameters.Add("kp2", xlParamTypeDecimal)
param2.SetParam xlConstant, 8230
работает.Поиски по интернету не дали работающего примера и поэтому напрашивается вывод:запрос с параметрами для Provider=VFPOLEDB не работает.



Исправлено 1 раз(а). Последнее : LUCIAN, 27.07.17 14:10
Ratings: 0 negative/0 positive
Re: EXCEL В OLEDB;Provider=VFPOLEDB.1 ИЗМЕНИТЬ ПРОГРАММНО СВОЙСТВО CommandText
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Возможно что этот механизм (с параметризованным запросом) и не работает с VFPOleDB провайдером. Тем более что он вообще и не предназначен для работы с ним, а скорее с данными с шарепоинт портала...

Впрочем, если выполнить запрос нужно однократно (не требуется автоматический рефреш, ну или его можно закодировать "вручную" - по тому же клику на кнопку) то можно пойти с другой стороны. Сначала создать адодб-шный рекордсет - в нём никаких проблем с параметрами при использовании VFPOLEDB провайдера нет - что из фокса, что из экселя. А потом уже при создании ListObject-а в качестве источника подсунуть этот самый рекордсет - он (ListObject) оттуда данные и возьмёт.
В принципе можно и вообще без ListObject-а обойтись, тупо перегнав данные из рекордсета в нужный Range
Sub test()
Dim oCon, oCmd, oPar1, oPar2, oRS As Object
Set oCon = CreateObject("ADODB.Connection")
Set oCmd = CreateObject("ADODB.Command")
oCon.Open "Provider=VFPOLEDB.1;Data Source=C:\test.dbc;Collating Sequence=RUSSIAN;DELETED=True;CODEPAGE=1251;MVCOUNT=16384;ENGINEBEHAVIOR=90;TABLEVALIDATE=3;REFRESH=5;VARCHARMAPPING=False;ANSI=True;REPROCESS=5"
oCmd.ActiveConnection = oCon
oCmd.CommandText = "Select * From test1 WHERE some_date BETWEEN ? AND ?"
Set oPar1 = oCmd.CreateParameter("from", 133)
oPar1.Value = #1/15/2017#
oCmd.Parameters.Append (oPar1)
Set oPar2 = oCmd.CreateParameter("to", 133)
oPar2.Value = #2/15/2017#
oCmd.Parameters.Append (oPar2)
Set oRS = oCmd.Execute
ActiveSheet.ListObjects.Add(SourceType:=xlSrcQuery, Source:=oRS, _
Destination:=Range("$A$1")).QueryTable.Refresh
oRS.Close
oCon.Close
End Sub

P.S. Этот код работает, но он предельно упрощён - в частности он только 1 раз может отработать, т.к. не проверяет что в указанном диапазоне уже ЕСТЬ "список" и тупо пытается его снова создать... Если речь про работу с шаблоном, и там изначально создан список, то можно в него данные подсунуть, т.е. не создавать список, а использовать существующий.
И да, если к VBA проекту подключить через References ADODB-ную библиотеку, то можно будет и в ObjectBrowser все методы/свойства/константы смотреть, да и в редакторе кода тоже. Например вместо 133 прописать "человеческое" имя константы adDBDate или как там её...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: EXCEL В OLEDB;Provider=VFPOLEDB.1 ИЗМЕНИТЬ ПРОГРАММНО СВОЙСТВО CommandText
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
LUCIAN
напрашивается вывод:запрос с параметрами для Provider=VFPOLEDB не работает.
Неверно сформулировано. Не работает именно механизм автоматической генерации всех этих ADODB-ных прибамбасов силами экселевского ListObject-а. Сам по себе VFP провайдер, ну и ADODB библиотека его использующая, без проблем работает с параметризованными запросами (правда с неименованными параметрами, что не всегда удобно).


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: EXCEL В OLEDB;Provider=VFPOLEDB.1 ИЗМЕНИТЬ ПРОГРАММНО СВОЙСТВО CommandText
LUCIAN
Автор

Сообщений: 343
Откуда: Лида Беларусь
Дата регистрации: 25.03.2008
Для простейшего запроса изобрёл такое решение:
[attachment 28057 QUERY.GIF]
Для кнопки "Произвести выборку" такой код:
Private Sub CommandButton1_Click()
With ActiveSheet.ListObjects.Add(SourceType:=0, Source:=Array( _
"OLEDB;Provider=VFPOLEDB.1;Data Source=F:\SBT\TTN\TTN.DBC;Mode=Share Deny None;Extended Properties="""";User ID="""";Mask Password=False;Ca" _
, _
"che Authentication=False;Encrypt Password=False;Collating Sequence=RUSSIAN;DSN="""";DELETED=True;CODEPAGE=1251;MVCOUNT=16384;ENGIN" _
, _
"EBEHAVIOR=90;TABLEVALIDATE=3;REFRESH=5;VARCHARMAPPING=False;ANSI=True;REPROCESS=5" _
), Destination:=Range("$I$1")).QueryTable
.CommandType = xlCmdSql
.CommandText = Array(Range("$A$2").Value)
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = True
.SourceConnectionFile = _
"C:\Documents and Settings\PETR1\Мои документы\Мои источники данных\OTGR_PR.odc"
.ListObject.DisplayName = "Таблица_OTGR_PR"
.Refresh BackgroundQuery:=False
End With
End Sub
Ratings: 0 negative/0 positive
Re: EXCEL В OLEDB;Provider=VFPOLEDB.1 ИЗМЕНИТЬ ПРОГРАММНО СВОЙСТВО CommandText
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Не надо так делать. НИКОГДА.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: EXCEL В OLEDB;Provider=VFPOLEDB.1 ИЗМЕНИТЬ ПРОГРАММНО СВОЙСТВО CommandText
LUCIAN
Автор

Сообщений: 343
Откуда: Лида Беларусь
Дата регистрации: 25.03.2008
Igor Korolyov
Не надо так делать. НИКОГДА.
А так можно?
Private Sub CommandButton1_Click()
Dim s0 As String
s0 = "SELECT Ttn.dato, Ttn.ser, Ttn.ttn, Sp_part.kodkl,RTRIM(Sp_part.nam)+' '+RTRIM(Rn.nam)+' '+RTRIM(IIF(Obl.kod=7000,SPACE(LEN(Obl.nam)),Obl.nam)) nam,SP_PRD.NAMP,CPR.KOL,CPR.SUMA, S_val.nam val,SP_PRD.KP, Ttn.n_dow, Ttn.wyd,Ttn.val kodv, Ttn.id_ttn, Sp_part.k_ter,NVL(Kurs.kurs,1.00) kurs, Ttn.op, Ttn.osn_otp,Sp_part.k_fond FROM (SELECT TTND.ID_TTN,ID_PRD,SUM(Ttnd.kol*(2*Sttn.op-1)) kol,SUM(Ttnd.suma*(2*Sttn.op-1)) suma FROM TTND INNER JOIN (SELECT ID_TTN,OP FROM TTN WHERE DATO BETWEEN CTOD('?') AND CTOD('?')) STTN ON STTN.ID_TTN=TTND.ID_TTN GROUP BY 1,2) CPR INNER JOIN TTN ON TTN.ID_TTN = CPR.ID_TTN INNER JOIN SP_PRD ON SP_PRD.ID_PRD = CPR.ID_PRD LEFT JOIN TTN!KURS ON DTOS(Kurs.data)+Kurs.val = DTOS(Ttn.dato)+Ttn.val, ttn!s_val,ttn!sp_part,ttn!sp_ter Rn,ttn!sp_ter Obl WHERE S_val.kod = Ttn.val AND Ttn.id_pol = Sp_part.id_part AND Rn.kod = Sp_part.k_ter AND Obl.kod = ROUND(Rn.kod,-3) ORDER BY 1,2,3"
Dim s As String
s = Replace(s0, "?", RTrim(Range("$C$7").Value), 1, 1)
s = Replace(s, "?", RTrim(Range("$C$9").Value), 1, 1)
Rem MsgBox s
With ActiveSheet.ListObjects("Таблица_OTGR_PR")
.Delete
End With
With ActiveSheet.ListObjects.Add(SourceType:=0, Source:=Array( _
"OLEDB;Provider=VFPOLEDB.1;Data Source=F:\SBT\TTN\TTN.DBC;Mode=Share Deny None;Extended Properties="""";User ID="""";Mask Password=False;Ca" _
, _
"che Authentication=False;Encrypt Password=False;Collating Sequence=RUSSIAN;DSN="""";DELETED=True;CODEPAGE=1251;MVCOUNT=16384;ENGIN" _
, _
"EBEHAVIOR=90;TABLEVALIDATE=3;REFRESH=5;VARCHARMAPPING=False;ANSI=True;REPROCESS=5" _
), Destination:=Range("$I$1")).QueryTable
.CommandType = xlCmdSql
.CommandText = s
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = True
.ListObject.DisplayName = "Таблица_OTGR_PR"
.Refresh BackgroundQuery:=False
End With
With ActiveSheet
.Columns("I:I").NumberFormat = "dd/mm/yyyy;@"
.Columns("L:L").NumberFormat = "@"
End With
End Sub
Ratings: 0 negative/0 positive
Re: EXCEL В OLEDB;Provider=VFPOLEDB.1 ИЗМЕНИТЬ ПРОГРАММНО СВОЙСТВО CommandText
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Это не настолько очевидно плохо, но всё равно плохо - SQL инъекция налицо. Конечно, если ты вообще не "закрываешь" сам модуль с кодом, то это не так уж и важно - юзер тупо зайдёт в редактор VBA и выполнит с твоей таблицей всё что угодно (даже если у него нет никакого фокса на машине). Впрочем, серьёзно говорить о безопасности/надёжности/защищённости системы с хранением данных в dbf не приходится

Чем не устраивает приведенный вариант с ADO рекордсетом? Там в чистом виде параметризованный запрос работает через тот же самый провайдер - и это правильно.
Всё одно ты рефреш списка "по кнопке" вызываешь - так там не проблема каждый раз в коде это и делать.


------------------
WBR, Igor
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 7 (Гостей: 7)

© 2000-2024 Fox Club 
Яндекс.Метрика