2015-12-14 8 views
5

संक्षेप में: मैं अपने क्लाइंट के लिए शेड्यूलर बना रहा हूं और बाधाओं के कारण, इसे एक एक्सेल फ़ाइल में होना चाहिए (जितना छोटा मुमकिन)। तो एक वर्कशीट यूआई के रूप में काम करता है और कोई अन्य टेबल या सेटिंग्स होगा।वीबीए-एसक्यूएल अद्यतन/INSERT/एक्सेल वर्कशीट से चुनें/

मैं एक वर्कशीट (जिसे "TblEmpDays" नाम दिया गया है) पर शेड्यूल डेटा के साथ काम करने के लिए SQL (जिसे मैं नया हूं) का उपयोग करने की कोशिश कर रहा हूं। तो मुझे इस वर्कशीट में/से रिकॉर्ड जोड़ने/अपडेट करने और पुनर्प्राप्त करने की आवश्यकता है। मैं कुछ मनमानी डेटा (और एक रेंज में पेस्ट) के साथ काम करने के लिए SELECT क्वेरी प्राप्त करने में सक्षम था। हालांकि, मैं काम करने के लिए INSERT या UPDATE प्राप्त करने में सक्षम नहीं हूं। मैंने इसे INSERT INTO [<table name>$] (<field names>) VALUES (<data>); के रूप में संरचित देखा है। हालांकि यह मेरे लिए एक रन-टाइम त्रुटि देता है "'-2147217900 (80040e14)' सिंटेक्स सम्मिलित में त्रुटि बयान में।"

मैं VBA का उपयोग कर रहा यह सब लिखने के लिए और मैं बनाने के लिए एक एसक्यूएल सहायक वर्ग बनाया क्वेरी निष्पादन आसान है।

स्पष्टीकरण के लिए, मेरा प्रश्न है: मुझे INSERT और UPDATE प्रश्नों को बनाने की आवश्यकता कैसे है? मैं क्या खो रहा हूँ? मैं जितना संभव हो उतना संबंधित जानकारी पोस्ट करने की कोशिश कर रहा हूं, इसलिए अगर मुझे कुछ याद आया तो मुझे बताएं।

कक्षा एसक्यूएल:

Private pCn ' As Database 
Private pResult 'As Recordset 
Private pSqlStr As String 

Public Property Get Result() 
    Result = pResult 
End Property 

Public Function Init() 
    Set pCn = CreateObject("ADODB.Connection") 

    With pCn 
     .ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 
          "Data Source=" & ThisWorkbook.FullName & ";" & _ 
          "Extended Properties=""Excel 12.0 Macro;HDR=YES;ReadOnly=False"";" 
     .Open 
    End With 

End Function 

Public Function Cleanup() 
    If Not (pCn Is Nothing) Then 
     pCn.Close 
     Set pCn = Nothing 
    End If 

    If Not pResult Is Nothing Then 
     Set pResult = Nothing 
    End If 

End Function 

Public Function CopyResultToRange(rg As Range) 
    If Not rg Is Nothing And Not pResult Is Nothing Then 
     rg.CopyFromRecordset pResult 
    End If 
End Function 

Public Property Get query() As String 
    query = pSqlStr 
End Property 
Public Property Let query(value As String) 
    pSqlStr = value 
End Property 

Public Function Execute(Optional sqlQuery As String) 
    If sqlQuery = "" Then 
     sqlQuery = query 
    End If 

    If Not pCn Is Nothing Then 
     Set pResult = pCn.Execute(sqlQuery, , CommandTypeEnum.adCmdText Or ExecuteOptionEnum.adExecuteNoRecords) 
    Else 
     MsgBox "SQL connection not established" 
    End If 

End Function 

निष्पादित समारोह:

Dim s As SQL ' this is the SQL class ' 
Dim tbl As String 
' rcDay=date string, rcIn & rcOut = time strings, rcVac=boolean string, rcSls=number string' 
Dim rcName As String, rcDay As String, rcIn As String, rcOut As String, rcVac As String, rcSls As String 
Dim qry As String 

tbl = "[TblEmpDays$]" 
qry = "INSERT INTO <tbl> (name, date, in, out, vac, sales)" & vbNewLine & _ 
     "VALUES ('<name>', '<date>', '<in>', '<out>', '<vac>', <sales>);" 

' Set rc* vars ' 

s.Init 
s.query = Replace(Replace(Replace(Replace(Replace(Replace(Replace(qry, _ 
            "<tbl>", tbl), _ 
            "<sales>", rcSls), _ 
            "<vac>", rcVac), _ 
            "<out>", rcOut), _ 
            "<in>", rcIn), _ 
            "<date>", rcDay), _ 
            "<name>", rcName) 
MsgBox s.query 
s.Execute 
s.Cleanup 

मैं एक भर में देखा है एक समाधान नहीं मिल रहा। मुझे यकीन है कि मैंने अभी सही वाक्यांश या कुछ सरल खोज नहीं किया है।

+0

एक्सेल में डेटाबेस को फिर से बनाने के लिए एक कठिन प्रयास है। क्या आपके पास जेट/एसीई डेटाबेस बनाने के लिए एमएस एक्सेस है? ध्यान दें: आपके उपयोगकर्ताओं को कभी भी एक्सेस का उपयोग करने की आवश्यकता नहीं है लेकिन आप अभी भी अपने यूआई कार्यपुस्तिका को अपने डेटा को रखने के लिए .accdb/.mdb फ़ाइल से कनेक्ट कर सकते हैं, फिर किसी भी/सभी SQL उपलब्ध का उपयोग कर सकते हैं। जेट/एसीई एसक्यूएल इंजन एक .dll फ़ाइल है जो विंडो उपयोगकर्ताओं के लिए उपलब्ध है (और केवल एक्सेस तक ही सीमित नहीं है)। – Parfait

+0

@ पैराफैट मुझे उसमें खोदना होगा (विवादित उत्तरों प्राप्त करना) ... क्या है। डीएल यह है और यह कहां स्थित है? शायद मैं पा सकता हूं कि अगर उनके पास पहुंच नहीं है। (मैं इस पूरे प्रोजेक्ट को सोच रहा हूं कि अगर मैं एक्सेस का उपयोग कर सकता हूं तो यह कितना आसान होगा) – CheeseMo

+0

उपयोगकर्ताओं को आमतौर पर विंडोज़/एसीई इंजन का उपयोग करने के लिए एमएस एक्सेस की आवश्यकता नहीं है जो आमतौर पर विंडोज़ के साथ स्थापित होता है। यह Notepad.exe की तरह है। रजिस्ट्री के तहत देखें, HKEY क्लास रूट: 'माइक्रोसॉफ्ट.एसीई.ओएलडीबी.12.0' और 'माइक्रोसॉफ्ट.जेईटी.ओएलडीबी 4.0'। इसके अलावा, उपयोगकर्ता .accdb फ़ाइलों का उपयोग करने के लिए ** मुफ्त ** [एक्सेस रनटाइम] (https://www.microsoft.com/en-US/download/details.aspx?id=39358) डाउनलोड कर सकते हैं (लेकिन डेवलपर के पास होना चाहिए पूरा कार्यक्रम)। – Parfait

उत्तर

1

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


के लिए धन्यवाद टिप्पणी में @Jeeped, अब मैं एक बेवकूफ की तरह लग रहा है। यह पता चला है कि मेरे तीन फ़ील्ड नाम आरक्षित शब्दों ("नाम", "तिथि", और "इन") का उपयोग कर रहे थे। यह हमेशा एक सूक्ष्म विवरण लगता है जो मुझे करता है ...

मैंने इन फ़ील्ड को मेरे वर्कशीट (तालिका) में बदल दिया और उपयुक्त कोड बदल दिया। मुझे इनपुट स्ट्रिंग को उचित डेटा प्रकारों में भी कास्ट करना पड़ा। मैं अभी भी बाहर विवरण के बाकी काम कर रहा हूँ, लेकिन यहाँ नई क्वेरी है:

qry = "INSERT INTO <tbl> (empName, empDay, inTime, outTime, vac, sales)" & vbNewLine & _ 
        "VALUES (CStr('<name>'), CDate('<date>'), CDate('<in>'), CDate('<out>'), " & _ 
         "CBool('<vac>'), CDbl(<sales>));" 

मैं जरूरत CDate() (# * के बजाय #) तो मैं एक स्ट्रिंग पास कर सकता है। तो #<date>#

0

अपनी परियोजना के लिए वर्कशीट की बजाय बैकएंड के रूप में एक रिलेशनल डेटाबेस का उपयोग करने पर विचार करें। आप यूआई स्प्रेडशीट को फ्रंटएंड के रूप में उपयोग करना जारी रख सकते हैं। एक विंडोज उत्पाद के रूप में, जेट/एसीई एसक्यूएल इंजन एक कामकाजी समाधान हो सकता है और यह एकाधिक उपयोगकर्ता को एक साथ पहुंच (रिकॉर्ड-स्तर लॉकिंग के साथ) की अनुमति देता है। इसके अतिरिक्त, जेट/एसीई Database Definition Language (DDL) और Database Maniupulation Language (DML) प्रक्रियाओं के लिए अपनी स्वयं की एसक्यूएल बोली से लैस है। और एक्सेल एडीओ/डीएओ वस्तुओं के माध्यम से जेट/एसीई से कनेक्ट हो सकता है। अन्य आरडीएमएस की तुलना में जेट/एसीई का एकमात्र अंतर यह है कि यह एक फ़ाइल स्तर डेटाबेस (सर्वर नहीं है) और आप SQL का उपयोग कर डेटाबेस नहीं बना सकते हैं। आपको पहले वीबीए या अन्य COM परिभाषित भाषा का उपयोग कर डेटाबेस फ़ाइल बनाना होगा।

नीचे डीएओ के साथ डेटाबेस बनाने, एडीओ के साथ तालिकाओं बनाने, क्रिया प्रश्नों को निष्पादित करने और वर्कशीट में एक रिकॉर्डसेट की प्रतिलिपि बनाने में वीबीए स्क्रिप्ट (क्लाइंट्स और ऑर्डर टेबल) के काम कर रहे उदाहरण हैं। अपने मैक्रोज़ को अपनी परियोजना में एकीकृत करें। त्रुटि प्रबंधन और डीबग का उपयोग करें। अपने ऐप को विकसित करने में सहायता के लिए प्रिंट करें। यदि आपके पास एमएस एक्सेस स्थापित नहीं है, तो .accdb फ़ाइल निर्देशिका में दिखाएगी लेकिन रिक्त आइकन के साथ। कोड के माध्यम से फ़ाइल को प्रबंधित करने के लिए कोई उपयोगकर्ता इंटरफ़ेस नहीं होगा।

Sub CreateDatabase() 
On Error GoTo ErrHandle 
    Dim fso As Object 
    Dim olDb As Object, db As Object 
    Dim strpath As String 
    Const dbLangGeneral = ";LANGID=0x0409;CP=1252;COUNTRY=0" 

    strpath = "C:\Path\To\Database\File.accdb" 

    ' CREATE DATABASE ' 
    Set fso = CreateObject("Scripting.FileSystemObject") 
    Set olDb = CreateObject("DAO.DBEngine.120") 

    If Not fso.FileExists(strpath) Then 
     Set db = olDb.CreateDatabase(strpath, dbLangGeneral) 
    End If 

    Set db = Nothing 
    Set olDb = Nothing 
    Set fso = Nothing 

    MsgBox "Successfully created database!", vbInformation 
    Exit Sub 

ErrHandle: 
    MsgBox Err.Number & " - " & Err.Description, vbCritical 
    Exit Sub 
End Sub 

Sub CreateTables() 
On Error GoTo ErrHandle 
    Dim strpath As String, constr As String 
    Dim objAccess As Object 
    Dim conn As Object 

    strpath = "C:\Path\To\Database\File.accdb" 

    ' CONNECT TO DATABASE ' 
    constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strpath & ";" 
    Set conn = CreateObject("ADODB.Connection") 
    conn.Open constr 

    ' CREATE TABLES (RUN ONLY ONCE) ' 
    conn.Execute "CREATE TABLE Clients (" _ 
        & " ClientID AUTOINCREMENT," _ 
        & " ClientName TEXT(255)," _ 
        & " Address TEXT(255)," _ 
        & " Notes TEXT(255)," _ 
        & " DateCreated DATETIME" _ 
        & ");" 

    conn.Execute "CREATE TABLE Orders (" _ 
        & " OrderID AUTOINCREMENT," _ 
        & " ClientID INTEGER," _ 
        & " Item TEXT(255)," _ 
        & " Price DOUBLE," _ 
        & " OrderDate DATETIME," _ 
        & " Notes TEXT(255)" _ 
        & ");" 

    ' CLOSE CONNECTION ' 
    conn.Close 
    Set conn = Nothing 

    MsgBox "Successfully created Clients and Orders tables!", vbInformation 
    Exit Sub 

ErrHandle: 
    MsgBox Err.Number & " - " & Err.Description, vbCritical 
    Exit Sub 

End Sub 

Sub RetrieveDataToWorksheet() 
On Error GoTo ErrHandle 
    Dim strpath As String, constr As String 
    Dim conn As Object, rs As Object 
    Dim fld As Variant 

    strpath = "C:\Path\To\Database\File.accdb" 

    ' OPEN CONNECTION ' 
    constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strpath & ";" 
    Set conn = CreateObject("ADODB.Connection") 
    Set rs = CreateObject("ADODB.Recordset") 

    conn.Open constr 
    rs.Open "SELECT * FROM Clients" _ 
      & " INNER JOIN Orders ON Clients.ClientID = Orders.ClientID;", conn 

    ' COPY FROM RECORDSET TO WORKSHEET ' 
    Worksheets(1).Activate 
    Worksheets(1).Range("A4").Select 

    ' COLUMN NAMES ' 
    For Each fld In rs.Fields 
     ActiveCell = fld.Name 
     ActiveCell.Offset(0, 1).Select 
    Next 

    ' ROW VALUES ' 
    Worksheets(1).Range("A5").CopyFromRecordset rs 

    ' CLOSE RECORDSET AND CONNECTION ' 
    rs.Close 
    conn.Close 

    Set conn = Nothing 
    Set rs = Nothing 
    Exit Sub 

ErrHandle: 
    MsgBox Err.Number & " - " & Err.Description, vbCritical 
    Exit Sub 
End Sub 

Sub ActionQueries() 
On Error GoTo ErrHandle 
    Dim strpath As String, constr As String 
    Dim conn As Object 

    strpath = "C:\Path\To\Database\File.accdb" 

    ' OPEN CONNECTION ' 
    constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strpath & ";" 
    Set conn = CreateObject("ADODB.Connection") 
    conn.Open constr 

    ' APPEND QUERY ' 
    conn.Execute "INSERT INTO Clients (ClientID, ClientName)" _ 
        & " VALUES (" & Worksheets(1).Range("A2") & ", '" & Worksheets(1).Range("B2") & "');" 

    conn.Execute "INSERT INTO Orders (ClientID, Item, Price)" _ 
        & " VALUES (" & Worksheets(1).Range("A2") & ", " _ 
        & "'" & Worksheets(1).Range("C2") & "', " _ 
        & Worksheets(1).Range("D2") & ");" 

    ' UPDATE QUERY ' 
    conn.Execute "UPDATE Clients " _ 
        & " SET Address = '" & Worksheets(1).Range("E2") & "'" _ 
        & " WHERE ClientID = " & Worksheets(1).Range("A2") & ";" 

    ' DELETE QUERY ' 
    conn.Execute "DELETE FROM Orders " _ 
        & " WHERE ClientID = " & Worksheets(1).Range("A2") & ";" 

    ' CLOSE CONNECTION ' 
    conn.Close 
    Set conn = Nothing 

    MsgBox "Successfully updated database!", vbInformation 
    Exit Sub 

ErrHandle: 
    MsgBox Err.Number & " - " & Err.Description, vbCritical 
    Exit Sub 
End Sub 
+0

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

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