2009-07-12 15 views
7

अरे, मैंने बस इतना सीखा कि कैसे मेरे एसक्यूएल स्टेटमेंट्स को वीबीए में रखा जाए (या कम से कम उन्हें लिखें), लेकिन मुझे नहीं पता कि डेटा कैसे वापस प्राप्त किया जाए?माइक्रोसॉफ्ट एक्सेस वीबीए में SQL क्वेरी से डेटा कैसे प्राप्त करूं?

मेरे पास प्रश्नों के आधार पर दो रूपों (चार्ट फॉर्म) हैं जो मैं नियमित रूप से समय-सीमा को बदलता हूं (जैसे महीने के लिए शीर्ष 10 बिक्री)। तब मेरे पास ऐसी प्रक्रियाएं हैं जो चार्ट ऑब्जेक्ट को स्वचालित रूप से पावरपॉइंट प्रस्तुति में ले जाती हैं। तो मेरे पास ये सभी प्रश्न पूर्व-निर्मित (जैसे 63) हैं, और चार्ट मिलान करने के लिए फॉर्म हैं (ओह, हाँ .... 63 ... मुझे पता है कि यह बुरा है), और फिर इन सभी चीजों को "खुले/करीबी "घटनाओं को आगे बढ़ाना (यह हैक होने पर मेरे सबसे अच्छे प्रयास की तरह .... या डोमिनोज़; जो भी आप पसंद करते हैं)।

तो मैं सीखने की कोशिश कर रहा था कि वीबीए में एसक्यूएल स्टेटमेंट का उपयोग कैसे करें, ताकि अंततः मैं वहां सब कुछ कर सकूं (मुझे अभी भी उन सभी चार्ट फॉर्मों को रखने की आवश्यकता हो सकती है लेकिन मुझे नहीं पता क्योंकि मुझे स्पष्ट रूप से समझ में कमी नहीं है)।

तो मैंने शीर्ष पर पूछा गया प्रश्न से अलग, क्या कोई सलाह दे सकता है? धन्यवाद

+1

खेद मैं हमेशा भूल जाते हैं .... मैं माइक्रोसॉफ्ट एक्सेस 2000 – Justin

+0

@Justin का उपयोग कर रहा है, अगर वे मदद की यह हमेशा ऊपर अच्छा लोग हैं, जो आप :) –

उत्तर

9

यह थोड़ा दिनांकित है, इसलिए आप book on the subject को पकड़ना चाहेंगे। लेकिन, यहां access resources और कुछ tutorials and examples का एक टन भी है। लेकिन, मूल रूप से ...

टिप्पणी प्रति: recordset class पर एक नजर डालें। इसमें फ़ील्ड नामक एक संग्रह होता है जो आपकी क्वेरी से वापस आने वाले कॉलम होते हैं। अपने स्कीमा जानने के बिना, यह कहना मुश्किल है, लेकिन कुछ ऐसा है ...

rs.MoveFirst 
Do While Not rs.EOF 
    'do something like rs("SomeFieldName") 
    rs.MoveNext 
Loop 

जैसा कि मैंने कहा, आपका सर्वश्रेष्ठ दांव इस विषय पर एक पुस्तक हड़पने के लिए है, वे उदाहरण के टन की है।

+1

नहीं सभी कर्सर प्रकार नीचे बाहर की मदद की RecordCount वापस आ जाएगी वोट करने के लिए अच्छा है। यह सुरक्षित नहीं है .OF ... –

+0

धन्यवाद और साइटों के लिए धन्यवाद! – Justin

+0

कोड उदाहरण डीएओ है और सभी रिकॉर्डसेट प्रकार रिकॉर्ड होने पर कम से कम 1 का रिकार्डकाउंट लौटाते हैं, इसलिए रिकॉर्डिंग <> 0 पर्याप्त है, यह जांचने के लिए ईओएफ और बीओएफ की जांच करने की कोई आवश्यकता नहीं है। यदि आप अपने कोड को किसी अन्य डेटा इंटरफ़ेस पर पोर्ट कर रहे हैं, तो आपका बिंदु प्रासंगिक है, लेकिन वर्तमान कोड उदाहरण में यह निश्चित रूप से आधार से पूरी तरह से बंद है, जो काफी स्पष्ट रूप से डीएओ है। –

1

हालांकि संकलित, वीबीए में एसक्यूएल स्टेटमेंट बनाने की कोशिश करने से आपका तरीका आसान है। याद रखें, अलग-अलग प्रश्नों को सहेजने से आप उन्हें दृष्टि से छेड़छाड़ कर सकते हैं। इसके अलावा, कुछ प्रदर्शन लाभ हैं।

एसक्यूएल की बेहतर समझ आपको अपने मौजूदा प्रश्नों को समेकित और सरल बनाने में मदद करेगी (अगर उन्हें सरलीकृत करने की भी आवश्यकता है। ऐसा लगता है जैसे वे बहुत काम कर रहे हैं, इसलिए आपको सभी 64 प्रश्नों की आवश्यकता हो सकती है)।

जिसके अनुसार, यह कोड में एसक्यूएल प्रश्नों पर अमल करने में बहुत आसान है:

Dim strSQL as String 
strSQL = "UPDATE Table MyTable SET fieldname = 1 WHERE fieldname = 0;" 
DoCmd.RunSQL strSQL 
+0

धन्यवाद। एकमात्र चीज जो मैं घबराहट/उलझन में हूं, इन चीजों में इन सभी वस्तुओं को है, और जब मुझे इसे फ्रंट एंड/एमडीई में डंप करने की आवश्यकता होती है। यह पहली बार होगा जब मैं कभी भी ऐसा कर रहा हूं क्योंकि वास्तव में एक्सेस के साथ मेरा सीमित अनुभव हमेशा पीछे की स्थिति में रखा गया है – Justin

+0

उपकरण में डेटाबेस स्प्लिटर का उपयोग करते समय, समय आने पर अन्य सभी चीज़ों से टेबल को अलग करना आसान है/डेटाबेस उपयोगिताएँ। –

2

एक पैरामिट्रीकृत QueryDef का प्रयोग करें और VBA से यह आह्वान।
क्वेरी डिजाइन करना आसान है ... आसानी से परीक्षण योग्य..और वीबीए या एक फॉर्म से आसानी से सुलभ।

dim qd as querydef 
set qd = currentdb.querydefs!myquerydef 

qd.parameters!parm1=val1 

....

या तो qd.execute

या

dim rs as recordset 
set rs = qd.openrecordset() 

YMMV ...

+0

धन्यवाद। मैं – Justin

+0

बीटीडब्लू का प्रयास करूंगा ... यह डीएओ पुस्तकालयों का उपयोग करता है। बीमा करें कि 'संदर्भ' में, आपने एडीओ से अधिक डीएओ का चयन किया है। – CMB

+0

एक सीमा यह है कि आप शीर्ष एन एसक्यूएल कथन में एन को पैरामीटर नहीं कर सकते हैं। –

2

यहाँ एक समारोह है कि आप लेने के लिए पुनर्रचना पर विचार हो सकता है एक स्ट्रिंग में, और आप अपने कोड में कहीं भी पुनः उपयोग करने में सक्षम होंगे।

तो एक CONST है या अपने SQL विवरण के लिये एक स्ट्रिंग बनाने, और आपके स्वच्छ में पॉप, गैर एसक्यूएल एक तर्क :)

यानी

strSQL = "SELECT * FROM Customer WHERE ID = " & EnsureParamIsNotSQLInjection(customerID) 

... तो फोन के रूप में स्ट्रिंग इंजेक्शन फ़ंक्शन/सब कहीं भी आपको रिकॉर्ड्स/डेटा/एक कथन निष्पादित करने की आवश्यकता है। डेटा-एक्सेस फ़ंक्शंस/सबस का एक मुट्ठी भर बनाने पर विचार करें जहां आप केवल एक अपडेट स्टेटमेंट चला सकते हैं, या एकल मान पुनर्प्राप्त कर सकते हैं, या एक पूर्ण उड़ा रिकॉर्डसेट को पुनः प्राप्त कर सकते हैं।

यहां कुंजी यह है कि ये सभी कार्य एक ही स्थान पर रहें और उन्हें सभी जगहों पर पुन: उपयोग करें। यहां वीबीस्क्रिप्ट में एक नमूना है।

Sub DoStuff(strSQL) 

    Set adoCon = Server.CreateObject("ADODB.Connection") 


    strConnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("db\Database.mdb") 
    'strConnString = "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" & Server.MapPath("db\Database.mdb") 

    adoCon.Open strConnString 

    Set rsMain = Server.CreateObject("ADODB.Recordset") 

    rsMain.Open strSQL, adoCon 

    Do While NOT rsMain.EOF 
     customerName = rsMain("CustomerName") 'silly example 
     RsMain.MoveNext 
    Loop 

    rsMain.Close 

    Set adoCon = Nothing 
End Sub 
+0

हाँ जो अच्छा लगता है। विचार बुरा नहीं है। मुझे पता है कि सार्वजनिक फ़ंक्शन को किसी फ़ॉर्म के उप (ईवेंट) में कैसे कॉल करना है, लेकिन कार्यों के बारे में क्या ... क्या वे वही काम करते हैं? – Justin

+0

@pcampbell: किसी भी कारण से आप ओडीबीसी कनेक्शन का उपयोग क्यों कर रहे हैं? यदि आप ओएलई डीबी कनेक्शन का उपयोग करते हैं तो आप कई एडीओ से लाभ नहीं उठाएंगे। "प्रदाता = माइक्रोसॉफ्ट.जेट.ओएलडीबी.4.0; डेटा स्रोत =" और सर्वर.मैपपैथ ("डीबी \ डाटाबेस.एमडीबी") – onedaywhen

+0

... और मुझे यकीन नहीं है कि यह 'सर्वर' ऑब्जेक्ट क्या है जो आप सेवा के लिए उपयोग कर रहे हैं एडीओ ऑब्जेक्ट्स (स्थानीय मशीन की रजिस्ट्री का उपयोग करने के लिए अधिक सामान्य) और अपनी डेटाबेस फ़ाइल के पथ को हल करें। अधिकांश लोगों पर विचार करें कि यहां सर्वर ऑब्जेक्ट का संदर्भ नहीं होगा और इन पंक्तियों पर केवल 'ऑब्जेक्ट आवश्यक' त्रुटियां प्राप्त होंगी। – onedaywhen

1

इस ऐसा लगता है कि कोई भी उल्लेख किया गया है, एक भी बचाया QueryDef के लिए और फिर रन टाइम पर अपने ग्राफ बाँध QueryDef के पुनर्लेखन के लिए है करने के लिए एक और तरीका है। अब, मैं अधिकांश संदर्भों के लिए सहेजी गई क्वेरीरीफ्स को बदलने की अनुशंसा नहीं करता हूं, क्योंकि यह फ्रंट एंड ब्लोट का कारण बनता है और आमतौर पर यह भी आवश्यक नहीं होता है (अधिकतर संदर्भ जहां आप सहेजे गए QueryDef का उपयोग करते हैं, उसे संदर्भ में एक या दूसरे तरीके से फ़िल्टर किया जा सकता है जिसमें वे उपयोग किया जाता है, उदाहरण के लिए, एक फॉर्म के रिकॉर्ड्ससोर्स के रूप में, आप बस DoCmd.OpenForm में एक तर्क पारित करते हैं)।

ग्राफ अलग हैं क्योंकि ग्राफ को चलाने वाले एसक्यूएल रनटाइम पर बदला नहीं जा सकता है।

कुछ ने पैरामीटर सुझाए हैं, लेकिन पैरामीटर के साथ एक एसक्यूएल स्ट्रिंग का उपयोग करने वाले ग्राफ पर एक फॉर्म खोलना डिफ़ॉल्ट पैरामीटर संवाद पॉप करने जा रहा है। एक तरीका यह है कि से बचने के लिए, मापदंड इकट्ठा करने के लिए एक संवाद फार्म का उपयोग करें और उसके बाद पैरामीटर के रूप में संवाद फार्म पर नियंत्रण के लिए संदर्भ सेट करने के लिए है जैसे:

PARAMETERS [Forms]![MyForm]![ID] Long; 

आप प्रपत्र संदर्भ का उपयोग कर रहे हैं, यह महत्वपूर्ण है कि आप ऐसा करते हैं, क्योंकि एक्सेस 2002 से, जेट अभिव्यक्ति सेवा नियंत्रण न होने पर हमेशा इन्हें सही तरीके से संसाधित नहीं करती है। उन्हें परिभाषित करने के रूप में पैरामीटर उस समस्या को सुधारता है (जो एक्सेस XP से पहले मौजूद नहीं था)।

एक स्थिति जिसमें आप ग्राफ के लिए क्वेरीरीफ को फिर से लिखना चाहिए, यदि आप उपयोगकर्ता को शीर्ष एन एसक्यूएल कथन में एन चुनने की अनुमति देना चाहते हैं। दूसरे शब्दों में, यदि आप चाहते हैं कि वे शीर्ष 5 या शीर्ष 10 या शीर्ष 20 चुनने में सक्षम हों, तो आपको सहेजी गई क्वेरीरीफ को बदलना होगा, क्योंकि एन को पैरामीटरकृत नहीं किया जा सकता है।

1

"यदि आप उपयोगकर्ता को शीर्ष एन एसक्यूएल कथन में एन चुनने की अनुमति देना चाहते हैं" - ठीक है, तो आप एक सहसंबंधित सबक्वायरी (गतिशील एसक्यूएल के बजाए) का उपयोग कर सकते हैं। (एएनएसआई-92 क्वेरी मोड वाक्य रचना):

CREATE PROCEDURE GetOrdersTopN 
(
:N INTEGER 
) 
AS 
SELECT O1.OrderDate, O1.CustomerID 
    FROM Orders AS O1 
WHERE :N >= (SELECT COUNT(*) + 1 
       FROM Orders AS O2 
       WHERE O1.OrderDate < O2.OrderDate); 

... लेकिन पिछली बार मैं पहुँच इंजन में अच्छी तरह से अनुकूलित नहीं किया गया था जाँच निर्माण के इस प्रकार के लिए (यह हल्का डाल करने के लिए)।

+0

धन्यवाद! यकीन नहीं है कि मैं अभी तक काफी हूं, लेकिन इस तरह मैं सीखता हूं! – Justin

संबंधित मुद्दे