Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I used the DATA-From Other Sources-From SQL Server controls to import a database table into my Excel workbook. It looks perfect, and refreshing data works like a charm.
However, whenever I make any changes to the table (editing, inserting or deleting rows), I cannot seem to find a way to push these changes to the database. This makes me wonder whether this is actually possible.
Can anybody tell me how to do this, or confirm that this is not supported?
When you make a 'live' table in Excel by linking to an external data source like you have described in this question, Excel manages this by using a QueryTable object behind the scenes.
QueryTable objects have the ability to be refreshed on demand, and to refresh on a periodic schedule defined by the user.
QuertyTable objects are NOT bi-directional. They can be used to import data into Excel, but not to write changes back to the data source.
QueryTable objects can be manipulated from VBA.
Custom VBA code can be written to automatically write to a data source any changes made by a user to a table. But this absolutely requires writing code... it is not a simple option that you can select from the Excel user interface for your table.
Can anybody tell me how to do this, or confirm that this is not supported?
Insert, update, and delete are not supported from the Excel user interface.
Since you didn't have an exact goal other than ,.. Can you, how to ? let me just dump my code that i KNOW works because i use it all the time. This is part of a custom ribbon that is on 20+ computer so they can update/merge their sales information into out database. This should help you out feel free to ask some questions. Basically how it works is creates SQL command, that creates a temp table then merge/updates against our database
Dim adoCN As ADODB.Connection
Dim sConnString As String
Dim sSQL, sSQLMerge As String
Dim Starting As Integer
''Find the starting point
For I = 1 To UBound(data, 2) - 1
If data(I, 0) <> "" Then
Starting = I
Exit For
End If
Next
'''This primes the temp table
'' into #tempTable " & vbCrLf
If LCase(CStr(data(Starting, 0))) = "null" Then
Else
sSQL = "select '" & replace(CStr(data(Starting, 0)), "'", "''") & "' as '" & _
replace(CStr(data(0, 0)), "'", "''") & "'"
End If
For I = 1 To UBound(data, 2) - 1
If LCase(replace(CStr(data(Starting, I)), "'", "''")) = "null" Then
sSQL = sSQL & ", '' as '" & _
replace(CStr(data(0, I)), "'", "''") & "'"
Else
sSQL = sSQL & ", '" & replace(CStr(data(Starting, I)), "'", "''") & "' as '" & _
replace(CStr(data(0, I)), "'", "''") & "'"
End If
Next
sSQL = sSQL & ", getdate() as 'UpdateDate', suser_sname() as 'UpdatedBy' into #tempTable " & vbCrLf
' this adds all the data to the temp table
For I = Starting + 1 To UBound(data, 1)
If replace(CStr(data(I, 0)), "'", "''") = "" Then 'Checks to see ifs it has prop id, if not skip
Else
If LCase(replace(CStr(data(I, 0)), "'", "''")) = "null" Then 'checks to see if null if so add blank
sSQL = sSQL & "union Select ''"
Else
sSQL = sSQL & "union Select '" & replace(CStr(data(I, 0)), "'", "''") & "'" 'if not null add value
End If
For II = 1 To UBound(data, 2) - 1
If LCase(replace(CStr(data(I, II)), "'", "''")) = "null" Then
sSQL = sSQL & ", ''"
Else
sSQL = sSQL & ", '" & replace(CStr(data(I, II)), "'", "''") & "'"
End If
Next
sSQL = sSQL & ", getdate(), suser_sname() " & vbCrLf
End If
Next
'GuidanceInputForm.SellerConditioning.Text = sSQL
''UserForm1.Label1.Caption = Len(sSQLMerge)
'GuidanceInputForm.Show
''Add Merge code
sSQLMerge = "Merge CommercialSandbox..MasterDataTape as t" & vbCrLf & _
" Using #temptable as S on (replace(t.[Property ID], '-','') = replace(s.[Property ID], '-','') and replace(t.[Event ID], '-','') = replace(s.[Event ID], '-','')) " & vbCrLf & _
" When NOT MATCHED BY TARGET THEN INSERT([" & data(0, 0) & "]"
For I = 1 To UBound(data, 2) - 1
sSQLMerge = sSQLMerge & ", [" & data(0, I) & "]"
Next
sSQLMerge = sSQLMerge & ", UpdateDate, UpdatedBy"
sSQLMerge = sSQLMerge & ") VALUES (s.[" & data(0, 0) & "]"
For I = 1 To UBound(data, 2) - 1
sSQLMerge = sSQLMerge & ", s.[" & data(0, I) & "]"
Next
sSQLMerge = sSQLMerge & ", s.UpdateDate, s.UpdatedBy"
sSQLMerge = sSQLMerge & ") " & vbCrLf & _
" When MATCHED THEN UPDATE SET t.[" & data(0, 0) & "] = s.[" & data(0, 0) & "]"
For I = 1 To UBound(data, 2) - 1
sSQLMerge = sSQLMerge & ", t.[" & data(0, I) & "] = s.[" & data(0, I) & "]"
Next
sSQLMerge = sSQLMerge & ", t.UpdateDate = s.UpdateDate, t.UpdatedBy = s.UpdatedBy"
sSQLMerge = sSQLMerge & ";"
'GuidanceInputForm.SellerConditioning.Text = sSQLMerge
''UserForm1.Label1.Caption = Len(sSQLMerge)
'GuidanceInputForm.Show
sConnString = "Provider=sqloledb;Server=ERPT01LAX01US.prod.auction.local\EDWALT;Database=Commercialsandbox;Integrated Security = SSPI"
Set adoCN = CreateObject("ADODB.Connection")
adoCN.CommandTimeout = 0
adoCN.Open sConnString
adoCN.Execute sSQL
adoCN.Execute sSQLMerge
adoCN.Close
Related
I am connecting to a SQL table via an Excel VBA script using using SQL Server vs Windows Authentication as we're creating a generic update application to be used by several different users. If I log into SQL Server Management Studio with the generic ID/pswd and SQL Server Authentication, I can successfully insert and delete rows. When I use the VBA script, I receive an error indicating that the INSERT or DELETE permission was denied. The VBA script works successfully against the same table in a different schema, but fails going against this schema. I am assuming it's something in the SQL environment, as it seems like it's forced to Windows Authentication regardless of how I make the connection. Any help would be greatly appreciated.
Updates:
Thanks for the responses. I hope this additional information helps. We are on SQL Server 15.04102.2, and I am using SQL Server Authentication with a generic application ID and PSWD that has update permissions (my individual windows account only has select permissions)
As I indicated in my initial post, if I execute this code against one test environment, the DELETE and INSERT work perfectly. When I execute it against a different environment, the connection is made, but I get the permissions error on the DELETE and INSERT. If I use the exact same credentials and use SQL Server Authentication to go directly to that environment, I can successfully execute the DELETE and INSERT statements.
Here is the error I receive on the DELETE statement. A similar error is received on the INSERT statement if I bypass the delete for a new add.
Error -2147217911 (The DELETE permission was denied on the object
‘BCG_CGS_DETAILS’, database ‘xxxxxxcustom’, schema ‘dbo’.) in
procedure Export CGS to SQL. sSQL = delete dbo.BCG_CGS_DETAILS where
[CGSNUM]= ‘CGS-xxxxx’ AND [PDPD_ID]= ‘xxxxx’ AND EFF_DT=’7/1/2021’
Here is the code I am executing.
Sub Export_CGS_to_SQL()
Dim cnn
Dim rst
Dim sSQL As String
Dim iRow As Integer
Dim sLINE, sCategory, sBCBSNC_Medical_Policy, sBCBSNC_Standard_Provisions As String
Dim sIn_Network_VALUE, sIn_Network_Type_of_payment, sIn_Network_Detail As String
Dim sOut_of_Network_VALUE, sOut_of_Network_Type_of_payment, sOut_of_Network_Detail As String
Dim sCustomized, sCGSNUM, sPDPD_ID, sEFF_DT As String
Dim lLastrow As Long
Dim sServer, sTable, sDatabase, sConnection As String
On Error GoTo errHandler
With Sheets("CGS Data")
sCGSNUM = .Cells(2, 12)
sPDPD_ID = .Cells(2, 13)
sEFF_DT = .Cells(2, 14)
If sCGSNUM = "" Or sPDPD_ID = "0" Or sEFF_DT = "" Then
MsgBox "One or more required fields is blank. Please make sure that the Product ID and Effective date are set correctly on the MISC tab, and that the CGS Number exists for row A06c on the Client Profile tab"
Exit Sub
End If
lLastrow = Cells(Rows.Count, 1).End(xlUp).Row
sServer = Worksheets("MACRO_DATA").Range("B6").Value
sTable = Worksheets("MACRO_DATA").Range("B7").Value
sDatabase = Worksheets("MACRO_DATA").Range("B8").Value
sConnection = Worksheets("MACRO_DATA").Range("F5").Value
'Create a new Connection object
Set cnn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")
If cnn.State <> 1 Then
sSQL = "Provider=SQLOLEDB;Data Source=" & sServer & "; Initial Catalog=" & sDatabase & ";" & sConnection & "; Trusted_Connection=yes"
cnn.Open (sSQL)
End If
Set rst.ActiveConnection = cnn
sSQL = "delete " & sTable & " where [CGSNUM]= '" & sCGSNUM & "' AND [PDPD_ID]= '" & sPDPD_ID & "' AND EFF_DT= '" & sEFF_DT & "'"
cnn.Execute sSQL
For iRow = 2 To lLastrow
sLINE = .Cells(iRow, 1)
If sLINE <> "" Then
sCategory = .Cells(iRow, 2)
sBCBSNC_Medical_Policy = .Cells(iRow, 3)
sBCBSNC_Standard_Provisions = .Cells(iRow, 4)
sIn_Network_VALUE = .Cells(iRow, 5)
sIn_Network_Type_of_payment = .Cells(iRow, 6)
sIn_Network_Detail = .Cells(iRow, 7)
sOut_of_Network_VALUE = .Cells(iRow, 8)
sOut_of_Network_Type_of_payment = .Cells(iRow, 9)
sOut_of_Network_Detail = .Cells(iRow, 10)
sCustomized = .Cells(iRow, 11)
sCGSNUM = .Cells(iRow, 12)
sPDPD_ID = .Cells(iRow, 13)
sEFF_DT = .Cells(iRow, 14)
'insert row into sDatabase
sSQL = "insert into " & sTable & "([LINE],[Category],[BCBSNC Medical Policy],[BCBSNC Standard Provisions],[In-Network_VALUE]," _
& "[In-Network_Type of payment],[In-Network Detail],[Out-of-Network_VALUE],[Out-of-Network_Type of payment],[Out-of-Network_Detail]," _
& "[Customized],[CGSNUM],[PDPD_ID],[EFF_DT])" _
& "values ('" & sLINE & "', '" & sCategory & "', '" & sBCBSNC_Medical_Policy & "', '" & sBCBSNC_Standard_Provisions & "', '" _
& sIn_Network_VALUE & "', '" & sIn_Network_Type_of_payment & "', '" & sIn_Network_Detail & "', '" & sOut_of_Network_VALUE & "', '" _
& sOut_of_Network_Type_of_payment & "', '" & sOut_of_Network_Detail & "', '" & sCustomized & "', '" & sCGSNUM & "', '" _
& sPDPD_ID & "', '" & sEFF_DT & "')"
cnn.Execute sSQL
End If
Next iRow
MsgBox "CGS Data successfully exported to " & sTable, vbInformation
cnn.Close
Set cnn = Nothing
End With
Exit Sub
errHandler:
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure Export CGS to SQL. sSQL = " & sSQL
cnn.Close
Set cnn = Nothing
End Sub
I have an Excel workbook with the below code -
Sub Button1_Click()
Dim conn As New ADODB.Connection
Dim iRowNo As Integer
Dim sFirstName, sLastName As String
With Sheets("Sheet1")
'Open a connection to SQL Server
conn.Open "Provider=SQLOLEDB;" & _
"Data Source=server1;" & _
"Initial Catalog=table1;" & _
"User ID=user1; Password=pass1"
'Skip the header row
iRowNo = 2
'Loop until empty cell in CustomerId
Do Until .Cells(iRowNo, 1) = ""
sFirstName = .Cells(iRowNo, 1)
sLastName = .Cells(iRowNo, 2)
'Generate and execute sql statement
' to import the excel rows to SQL Server table
conn.Execute "Insert into dbo.Customers (FirstName, LastName) " & _
"values ('" & sFirstName & "', '" & sLastName & "')"
iRowNo = iRowNo + 1
Loop
MsgBox "Customers imported."
conn.Close
Set conn = Nothing
End With
End Sub
This opens up a connection to my database and inputs the values from the stated columns.
The primary key is an incremental key on the database. The problem is it will copy ALL values.
I'd like to add new rows of data into the Excel Sheet and only insert those rows that don't already exist.
I've tried different methods ('merge', 'if exist', if not exist', etc.) but I can't get it right.
The solution has to be through VBA. Setting up a link using SSMS is not an option.
I understand that it may be possible to use temporary tables and then trigger a procedure which performs the merge but I want to look into that as a last resort. Haven't read up on it yet (making my way through my MS SQL bible book) but I'm hoping it won't be necessary.
---Update from #Kannan's answer---
New portion of VBA -
conn.Execute "IF EXISTS (SELECT 1 FROM dbo.Customers WHERE FirstName = '" & sFirstName & "' and LastName = '" & sLastName & "') " & _
"THEN UPDATE dbo.customers SET WHERE Firstname = '" & sFirstName & "' and LastName = '" & sLastName & "' " & _
"ELSE INSERT INTO dbo.Customers (FirstName, LastName) " & _
"VALUES ('" & sFirstName & "', '" & sLastName & "')"
This returns error 'Incorrect syntax near the keyword 'THEN'.
Your SQL query isn't quite right - there is no THEN in a SQL IF.
Also, you don't need to do anything if it does exist, so just use if not exists.
"IF NOT EXISTS (SELECT 1 FROM dbo.Customers WHERE FirstName = '" & sFirstName & "' and LastName = '" & sLastName & "') " & _
"INSERT INTO dbo.Customers (FirstName, LastName) " & _
"VALUES ('" & sFirstName & "', '" & sLastName & "')"
This should do it for you.
Sub Button_Click()
'TRUSTED CONNECTION
On Error GoTo errH
Dim con As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim strPath As String
Dim intImportRow As Integer
Dim strFirstName, strLastName As String
Dim server, username, password, table, database As String
With Sheets("Sheet1")
server = .TextBox1.Text
table = .TextBox4.Text
database = .TextBox5.Text
If con.State <> 1 Then
con.Open "Provider=SQLOLEDB;Data Source=" & server & ";Initial Catalog=" & database & ";Integrated Security=SSPI;"
'con.Open
End If
'this is the TRUSTED connection string
Set rs.ActiveConnection = con
'delete all records first if checkbox checked
If .CheckBox1 Then
con.Execute "delete from tbl_demo"
End If
'set first row with records to import
'you could also just loop thru a range if you want.
intImportRow = 10
Do Until .Cells(intImportRow, 1) = ""
strFirstName = .Cells(intImportRow, 1)
strLastName = .Cells(intImportRow, 2)
'insert row into database
con.Execute "insert into tbl_demo (firstname, lastname) values ('" & strFirstName & "', '" & strLastName & "')"
intImportRow = intImportRow + 1
Loop
MsgBox "Done importing", vbInformation
con.Close
Set con = Nothing
End With
Exit Sub
errH:
MsgBox Err.Description
End Sub
Add a reference to:
Microsoft ActiveX Data Objects 2.8 Library
FYI, my sheet looks like this.
You can use sql query like this:
IF Exists ( Select 1 from dbo.customers where Firstname = '" & sFirstName & "' and LastName = '" & sLastName & "' THEN Update dbo.customers set --other columns where Firstname = '" & sFirstName & "' and LastName = '" & sLastName & "'
ELSE Insert into dbo.Customers (FirstName, LastName) " & _
"values ('" & sFirstName & "', '" & sLastName & "')"
Not sure about the syntax for excel and C#, you can correct that similar to this query
I am opening an SQL Server Connection in EXCEL VBA and on the objMyCmd.Execute line when it is using the SQL script I am getting this error message:
"Run-time error '-2147217900 (80040e14)') Automation error"
I have reviewed other SO posts that seem to reference an issue with the connection string itself, but I don't believe that is the issue as I am able to pull the first few variables listed when eliminating the rest of the SQL script.
I have attempted to review the SQL code to see if I am using an incorrect format, or if the language is not written properly and I am not able to determine the issue. I am hoping with some Q & A we may notice something I have missed in how this is written? Please let me know if there is additional information I can provide, below is the code up to the point of error.
Sub SQL_GetAgentChart()
Dim dtDate As Date
Dim myTable As ListObject
Dim DataServer As String
Dim Database As String
Dim constring As String
DataServer = "GLSSQLMADP2"
Database = "PERF_MGMT_BWRSRV_PROD"
constring = "Driver={SQL Server};Server=" & DataServer & "; Database=" & Database & "; Trusted_Connection=yes"
Dim AVStartDate As Date
Dim AVEndDate As Date
Dim RepID As Long
'Declare variables'
Set objMyConn = New ADODB.Connection
Set objMyCmd = New ADODB.Command
Set objMyRecordset = New ADODB.Recordset
Set myTable = Worksheets("Witness").ListObjects("tblWitness")
AVStartDate = DateValue("Mar 01, 2016")
AVEndDate = DateValue("Mar 31, 2016")
RepID = 2040
'Open Connection'
objMyConn.ConnectionString = constring
objMyConn.Open
'Set and Excecute SQL Command'
Set objMyCmd.ActiveConnection = objMyConn
objMyCmd.CommandText = " " & _
"SELECT PERSN_XTRNL_ID_NR, SOURCE, LOGGINGTS, DD7, CUREREASON, CUREDATE, LNSTATUS " & _
"FROM TTB " & _
"WITH INCALL AS (SELECT T.CUREREASON, CUREVALUE " & _
"FROM TTB T " & _
"JOIN PERSONNEL P ON T.PERSONNELID = P.PERSONNELID " & _
"LEFT JOIN CURETRANSLATE C ON T.CUREREASON = C.CUREREASON AND T.LNSTATUS = C.STATUS " & _
"WHERE T.PERSONNELID = " & RepID & " " & _
"AND LOGGINGTS > '" & AVStartDate & "' " & _
"AND LOGGINGTS < '" & AVEndDate + 1 & "' " & _
"AND INCOMING = 1 " & _
"AND DD7 > 0), OUTCALL AS (SELECT T.CUREREASON, CUREVALUE " & _
"FROM TTB T " & _
"JOIN AVAYA A ON T.UID = A.TTBUID " & _
"LEFT JOIN CURETRANSLATE C ON T.CUREREASON = C.CUREREASON AND T.LNSTATUS = C.STATUS " & _
"WHERE PERSONNELID = " & RepID & " " & _
"AND LOGGINGTS > '" & AVStartDate & "' " & _
"AND LOGGINGTS < '" & AVEndDate + 1 & "' " & _
"AND INCOMING = 0 " & _
"AND A.AVAYAGROUP IN ('15', '1A', '1B', '1C', '1D', '1E', '1F', '1G', '1H') " & _
"AND DD7 > 0) "
objMyCmd.CommandType = adCmdText
objMyCmd.Execute
I have a table in MS Access 2003 in which I want to archive all old data.
The criteria is that the creation data should be less than a specific date.
I can write a SQL statement to select them, but I don't know how to move them to another database/table? Assuming that the archive database/table is already created and data structure matches current table.
Also how I can make sure that all data which is moved to archive table is removed from current table?
I want to write VBA code to run the command check that data is archived correctly.
You want to 1) move data meeting certain criteria from one table to another, existing table with the same format. 2) You want to "make sure that all data which is moved to archive table is removed from current table." And 3) you "want to write VBA code to run the command check that data is archived correctly."
Contrary to popular opinion, Access does support transactions (the claim that Access SQL does not support transactions is true, but we can still use transactions in VBA code). So modifying code in this post to use transactions in a workspace, I believe this would do the trick (tested in Access 2010 using DAO).
The code to lock, get counts and unlock is not really necessary, and may increase the difficulty of implementing the archive, since it will require that no one be writing to the table while you're updating it. And if it did find a problem, Access does not support transaction logging, so you would have a very short list of options as to how to fix it. But it sounded like you wanted to be absolutely sure the counts were correct, so this adds another level, arguably unnecessary, of checking.
Option Compare Database
Option Explicit
Sub ArchiveOldRecords()
Dim nSourceCount As Long, nMoveCount As Long, nDestCount As Long
Dim strSQL As String, sMsg As String
Dim rsLock As DAO.Recordset
Dim rsBefore As DAO.Recordset, rsAfter As DAO.Recordset
Dim wrk As Workspace, db As DAO.Database
Const strcTableSource As String = "t_TestWithDate" ' Move records FROM table
Const strcTableArch As String = "t_ArchiveTestWithDate" ' Move records TO table
Const strcWHERE As String = " WHERE field2 < " _
& "DATEADD(""yyyy"", -1, Date())" ' Select date field and DATEADD params
Const strcCount As String = "SELECT COUNT(*) As "
On Error GoTo TrapError
Set db = CurrentDb
Set wrk = DBEngine.Workspaces(0)
' Lock table - so no one can add/delete records until count is verified
Set rsLock = db.OpenRecordset(strcTableSource, dbOpenTable, dbDenyWrite)
' Get initial table counts
Set rsBefore = db.OpenRecordset( _
strcCount & "SourceCount, " _
& "(SELECT COUNT(*) FROM " & strcTableSource _
& strcWHERE & ") As MoveCount, " _
& "(SELECT COUNT(*) FROM " & strcTableArch & ") As DestCount " _
& "FROM " & strcTableSource & ";", dbOpenForwardOnly)
nSourceCount = rsBefore!SourceCount
nMoveCount = rsBefore!MoveCount
nDestCount = rsBefore!DestCount
rsBefore.Close
wrk.BeginTrans
' Copy records
strSQL = "INSERT INTO " & strcTableArch _
& " SELECT * FROM " & strcTableSource & " " & strcWHERE & ";"
db.Execute strSQL, dbFailOnError
' Unlock table - only needed for counts
rsLock.Close
Set rsLock = Nothing
' Delete copied records
strSQL = "DELETE * FROM " & strcTableSource & " " & strcWHERE & ";"
db.Execute strSQL, dbDenyWrite + dbFailOnError
' Lock table - only needed for counts
Set rsLock = db.OpenRecordset(strcTableSource, dbOpenTable, dbDenyWrite)
wrk.CommitTrans
' Get final table counts
Set rsAfter = db.OpenRecordset( _
strcCount & "SourceCount, " _
& "(SELECT COUNT(*) FROM " & strcTableSource _
& strcWHERE & ") As MoveCount, " _
& "(SELECT COUNT(*) FROM " & strcTableArch & ") As DestCount " _
& "FROM " & strcTableSource & ";", dbOpenForwardOnly)
' Double-check counts
If (rsAfter!SourceCount <> nSourceCount - nMoveCount) _
Or (rsAfter!DestCount <> nDestCount + nMoveCount) _
Or (rsAfter!MoveCount > 0) Then
sMsg = vbNewLine
sMsg = sMsg & "Records in " & strcTableSource & " before: "
sMsg = sMsg & nSourceCount
sMsg = sMsg & vbTab & "after: "
sMsg = sMsg & rsAfter!SourceCount
sMsg = sMsg & vbNewLine
sMsg = sMsg & "Records to archive from " & strcTableSource & ": "
sMsg = sMsg & nMoveCount
sMsg = sMsg & vbTab & "after: "
sMsg = sMsg & rsAfter!MoveCount
sMsg = sMsg & vbNewLine
sMsg = sMsg & "Records in " & strcTableArch & " before: "
sMsg = sMsg & nDestCount
sMsg = sMsg & vbTab & "after: "
sMsg = sMsg & rsAfter!DestCount
MsgBox "Count double-check failed" & sMsg
End If
Exit_Sub:
On Error Resume Next
' Unlock table and close recordsets
rsLock.Close
rsBefore.Close
rsAfter.Close
Set rsBefore = Nothing
Set rsAfter = Nothing
Set rsLock = Nothing
Set db = Nothing
Set wrk = Nothing
Exit Sub
TrapError:
MsgBox "Failed: " & Err.Description
wrk.Rollback
Err.Clear
Resume Exit_Sub
End Sub
There is no MOVE command but you can copy the records across to the target and then use a similar query to remove them from the source when you are sure you have no Paste Errors.
INSERT INTO MyArchive (fld1, fld2, fld3, fld4) SELECT fld1, fld2, fld3, fld4 FROM MyTable WHERE fld4 < DATEADD("y", -5, Date())
That copies across everything older than 5 years. After confirming the transfer,
DELETE * FROM MyTable WHERE fld4 < DATEADD("y", -5, Date())
That's off the top of my head and I transition between T-SQL and MS Access a fair bit but I think that is pretty solid Access query code. Your own field lists will vary accordingly.
If cell.Value <> "" Then
uid = cell
lname = Left(Replace(Range(cell.Address).Offset(0, 1), "'", ""), 50)
fname = Replace(Range(cell.Address).Offset(0, 2), "'", "")
stat = Replace(Range(cell.Address).Offset(0, 3), "'", "")
role = Left(Replace(Range(cell.Address).Offset(0, 4), "'", ""), 50)
iqn = Replace(Range(cell.Address).Offset(0, 5), "'", "")
sdate = Format(Replace(Range(cell.Address).Offset(0, 6), "'", ""), "yyyy-mm-dd")
bdate = Format(Replace(Range(cell.Address).Offset(0, 7), "'", ""), "yyyy-mm-dd")
rodate = Format(Replace(Range(cell.Address).Offset(0, 8), "'", ""), "yyyy-mm-dd")
End If
hirereason = Replace(Range(cell.Address).Offset(0, 9), "'", "")
roreason = Replace(Range(cell.Address).Offset(0, 10), "'", "")
sql = "BEGIN TRAN IF EXISTS (SELECT * FROM " & TableName & " WITH (updlock, serializable)"
sql = sql & " WHERE UID = '" & uid & "')"
sql = sql & " BEGIN"
sql = sql & " UPDATE" & TableName
sql = sql & " SET LName='" & lname & "', FName='" & fname & "'"
sql = sql & ", Status='" & stat & "', Role='" & role & "'"
sql = sql & ", IQNRole='" & iqn & "', StartDate='" & sdate & "'"
sql = sql & ", BillableDate='" & bdate & "', RollOffDate='" & rodate & "'"
sql = sql & ", HireReason='" & hirereason & "', RollOffReason='" & roreason & "'"
sql = sql & " WHERE UID = '" & uid & "'"
sql = sql & " END"
sql = sql & " ELSE BEGIN"
sql = sql & " INSERT " & TableName & " (UID, LName, FName, Status, Role, IQNRole, StartDate"
sql = sql & ", BillableDate, RollOffDate, HireReason, RollOffReason)"
sql = sql & " VALUES('" & uid & "', '" & lname & "', '" & fname & "', '" & stat & "'"
sql = sql & ", '" & role & "', '" & iqn & "', '" & sdate & "', '" & bdate & "', '" & rodate & "'"
sql = sql & ", '" & hirereason & "', '" & roreason & "')"
sql = sql & " END COMMIT TRAN"
Cn.Execute (sql)
End If
I have some values and I'm formatting the date values which come is as string to date. If I run this as is it puts a default value for "" into the DB as 1900-1-1. I want the NULL values to actually stay in the DB and not be over-written. Furthermore I want them to update a cell with NULL if say it didn't use to be but now is.
I tried wrapping my value rodate in an IF statement and tried validating it against NULL, NOTHING, and EMPTY to say if it is one of these UPDATE DB with "NULL" but it doesn't do it. Date still comes out 1900-1-1. Any ideas?
Dim roDate
'...
'...
rodate = Trim(cell.Offset(0, 8).Value)
If len(rodate)=0 Then
rodate = null
else
rodate = "'" & Format(rodate, "yyyy-mm-dd") & "'"
end if
'....
'....
'note no single quote here around rodate
sql = sql & ", BillableDate='" & bdate & "', RollOffDate=" & rodate
'...
'...
I'm confused, not sure if I get this question right.
The only thing I understood from it is that you are struggling with saving a date as NULL in the database.
NULL and an empty string are not the same.
Try and see if this works:
dim vNull as variant
vNull = Null
if sDate = "" then
//Save vNull instead of Date
end if
I don't believe that you can capture NULL in a string datatype.
Edit
Perhaps stupid that I didn't think of this before, but instead of an empty string, can't you just put the string "NULL" in the query string?