MS Access Inventory and Auto Increment Values - ms-access

I'm fairly new to MS Access, but I'm trying to make a user friendly database to maintain an inventory of blood products.
I need to track a few different points of information.
DIN
Blood Type
Product Type
Expiration Date
I've already figured out a system to add products to a table using a form, but right now it's not very specific to my needs.
To increase tracking capability I wanted to be able to assign new inventory items to different rack #s and storage units. I have 15 different storage units and I have literally hundreds of racks I could be filling.
So what I'm having trouble with is streamlining the process of assigning my units to different racks incrementally. I have an excel spreadsheet that does this, but it's not friendly to the end user.
So what I'd like to do is have my form accept barcode scans from the product which contains all the information I need except for the rack # and position in the rack. The idea is that I want to be able to use the form to put the Rack # in and then have the form automatically increment the slot in the rack as I scan them in.
I already know how to have default values carry over from the last form so I don't need to retype the rack # or freezer # as I fill the rack.
The format I'm going for is 1-1, 1-2, 2-1, 2-2 and so on until I reach position 8-2. Each rack holds 16 units. So I'd like for the slot # to autoincrement up to 8-2 then reset and clear the rack # field.
Any assistance would be greatly appreciated.

You can simply increment a number by 1 for each reading.
Dim n As Long
Dim Position As String
n = n + 1
Position = (((n - 1) \ 2) Mod 8) + 1 & "-" & ((n - 1) Mod 2) + 1
Or, not using a number but reading the last Position:
n = Val(Split(LastPosition, "-")(0)) * 2 + Val(Split(LastPosition, "-")(1)) - 1
Position = (((n - 1) \ 2) Mod 8) + 1 & "-" & ((n - 1) Mod 2) + 1
Edit:
If you haven't done already, add an AutoNumber field to the table names, say, Id.
Create a function like this:
Public Function RackPosition(ByVal Number As Long) As String
Dim Index As Long
Dim Position As String
' Avoid zero and negative numbers.
Index = Abs(Number) + 1
Position = (((Index - 1) \ 2) Mod 8) + 1 & "-" & ((Index - 1) Mod 2) + 1
RackPosition = Position
End Function
Then, in your form, include a textbox to display the rack position using this expression as ControlSource:
=IIf(IsNull([Id]),Null,RackPosition(Nz([ID],0)))

This is what to do:
Table: Change the data type of Freezer and Rack to Number, Integer
Form: Adjust the three textboxes, Freezer, Rack, and Position to be rught aligned
Module: Adjust to read like this:
-
Option Compare Database
Option Explicit
Public Function RackPosition(ByVal Number As Long) As String
Dim Index As Long
Dim Position As String
' Avoid zero and negative numbers.
Index = Abs(Number) + 1
Position = (((Index - 1) \ 2) Mod 8) + 1 & "-" & ((Index - 1) Mod 2) + 1
RackPosition = Position
End Function
Form module: Adjust like this:
-
Private Sub SetPosition()
Const Positions As Integer = 16
Dim Number As Integer
Dim Criteria As String
If Nz(Me!Freezer.Value, 0) + Nz(Me!Rack.Value, 0) = 0 Then
' No rack data.
ElseIf IsNull(Me!Position.Value) Then
' Calculate next available position.
Criteria = "[Freezer] = " & Me!Freezer.Value & " And [Rack] = " & Me!Rack.Value & " And [Position] Is Not Null"
Number = DCount("*", "Blood Inventory (Raw)", Criteria)
If Number >= Positions Then
MsgBox "This rack is full", vbInformation + vbOKOnly, "Position"
Else
Me!Position.Value = RackPosition(Number)
End If
End If
End Sub
Private Sub Freezer_AfterUpdate()
SetPosition
End Sub
Private Sub Text42_AfterUpdate()
SetPosition
End Sub
Now, when Freezer and Rack is entered, Position is filled out automatically.

Related

have a number like 000x-000yy that counts the number of invoices issued each month and year so that it resets after each month and year [duplicate]

I have autonumber field in MS Access.
Here, it's starting with 1, 2, 3,…
But I want to enumerate numbers starts, with
2017ICLAA001, 2017ICLAA002, 2017ICLAA003,…
How to do that?
Simply type "2017ICLAA"000 into the ID field's Format Property
Should be able to figure out what you want with this since "2017...." is not always going to be the same and if you change it then it will jack up your database.
Example of Year-Number output: 17-0001
When the year changes the number auto resets to 1, because it checks the date then the number value which is incremental from 1 to 9,999 each year. You can delete records and it won't affect numbering since it always checks for the largest integer based on the current year, which is defined by your computers time/clock.
Must have the following columns: [AutonumberID] [DateCreated] [ColumnForYear-Number]
You should set the "[DateCreated]" column's "Default Value" in the Table's DesignView to "=Date()" (without quotes) so a date is added automatically when creating a record.
Add the following to your form's [Event Procedure] BEFOREINSERT otherwise if you update content in the record later (BeforeUpdate) it WILL change the record number everytime a change is made. You've been warned!
Do not use the date of a "[Last Modified]" type of column otherwise you will regret it in the future if you change/update anything in the record when the year changes and edits are made (think about it). Ensure you have a dedicated "[DateCreated]" column that doesn't change after inserting/adding the record no matter what year you decide to make any changes.
Here is the code:
Option Compare Database
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim vLast As Variant
Dim iNext As Integer
vLast = DMax("[ColumnForYear-Number]", "[Table]", "[ColumnForYear-Number] LIKE '" & _
Format([txtDateCreated], "yy\*\'"))
If IsNull(vLast) Then
iNext = 1
Else
iNext = Val(Right(vLast, 4)) + 1
End If
Me![ColumnForYear-Number] = Format([txtDateCreated], "yy") & "-" & Format(iNext, "0000")
End Sub
To get more than 9,999 records in one year change the number 4 in Val(Right(vLast, 4)) to a larger integer, then change the zeros in Format(iNext, "0000") to reflect the number of placeholders. The number 4 and there are four zeros. The same thing applies to the year, just change anywhere there is "yy" to "yyyy" for a four digit year. When making changes ensure the data type for the table's field/column can accept the total characters to be calculated or it will chop off any excess characters. Default is usually 255 characters for text however if your's says 8 characters are allowed for the [ColumnForYear-Number] and you are trying to add 9 or more then you will get frustrated troubleshooting a simple problem. Just FYI.
"[txtDateCreated]" is where the actual date entry exists and not the same as "[DateCreated]" which is the column name, unless you named your label that under the "Other" tab in Property Sheet. In other words columns are [columnname] and the textbox area where values are added/changed/viewed in FORMS should be labeled [txtcolumnname] (minus the brackets of course).
Additional options that are already configured into the format you request are listed in the next response (see below).
Since I had some more time on my hands I decided to answer your question more directly with a couple of options. My assumptions are: (1) You want the year 2017 to change automatically and (2) a prefix you define ICLAA followed by (3) an incremental number 001 that resets with each new year and (4) this is for a form with entry boxes (hence [txt...]).
Table Columns Required:
[AutoNumber] <=Not used here, it's just to show it still exists
[Column4UniqueValue] set the data type to Short Text and ensure your columns field size is set to 12 or more otherwise it will not work and will kick an error.
[DateCreated] set to Date/Time with format as General Date default value set =Date(), set Show Date Picker to Never for good measure, and set Locked value to Yes so user cannot change\override the value in the form. Note: this column [DateCreated] is not required if you decide to go with option two (2) listed below.
After you created the columns above in your table go to your form and add the new fields onto the form, click inside the newly added text field box and set its Other name as txt.... , then go into VBA Code Builder [Alt+F11] and add the code from either option one or option two.
Option One (with DateCreated field):
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim Prefix As String
Dim vLast As Variant
Dim iNext As Integer
Prefix = "ICLAA"
vLast = DMax("[Column4UniqueValue]", "[tblSource]", "[Column4UniqueValue] LIKE '" & Format([txtAreaOfDateCreated], "yyyy\*\") & Prefix & "*'")
If IsNull(vLast) Then
iNext = 1
Else
iNext = Val(Right(vLast, 3)) + 1
End If
Me![txtAreaOfColumn4UniqueValue] = Format([txtAreaOfDateCreated], "yyyy") & Prefix & Format(iNext, "000")
End Sub
Option Two (without DateCreated field):
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim Prefix As String
Dim vLast As Variant
Dim iNext As Integer
Prefix = "ICLAA"
vLast = DMax("[Column4UniqueValue]", "[tblSource]", "[Column4UniqueValue] LIKE '" & Format(Date, "yyyy\*\") & Prefix & "*'")
If IsNull(vLast) Then
iNext = 1
Else
iNext = Val(Right(vLast, 3)) + 1
End If
Me![txtAreaOfColumn4UniqueValue] = Format(Date, "yyyy") & Prefix & Format(iNext, "000")
End Sub
Your end results will look exactly like this 2017ICLAA001 and auto increment each year starting from one. Test it by creating a few records then change your computer's date/time clock to a later or earlier year and add another record. It should change with the year and when the year changes it will auto increment to the next highest value for that year. You can test this by toggling the computer year back and forth just to watch the values remain consistent when you add new records.

Auto-Increment Letter to specific Number

I need help at Auto-Incrementing a letter.
A description field in Table1 has values like: B39
This Table1 Record, has related records in Table2:
B39_a
B39_b
B39_c
B39_d
All I want to do is that the description in Table2 automatically takes the record at table1 and adds the specific letter. It always starts with "a" and never reaches the full alphabet.
I already tried some code from this site: http://www.freevbcode.com/ShowCode.asp?ID=5440
Function IncrementString(ByVal strString As String) As String
'
' Increments a string counter
' e.g. "a" -> "b"
' "az" -> "ba"
' "zzz" -> "aaaa"
'
' strString is the string to increment, assumed to be lower-case alphabetic
' Return value is the incremented string
'
Dim lngLenString As Long
Dim strChar As String
Dim lngI As Long
lngLenString = Len(strString)
' Start at far right
For lngI = lngLenString To 0 Step -1
' If we reach the far left then add an A and exit
If lngI = 0 Then
strString = "a" & strString
Exit For
End If
' Consider next character
strChar = Mid(strString, lngI, 1)
If strChar = "z" Then
' If we find Z then increment this to A
' and increment the character after this (in next loop iteration)
strString = Left$(strString, lngI - 1) & "a" & Mid(strString, lngI + 1, lngLenString)
Else
' Increment this non-Z and exit
strString = Left$(strString, lngI - 1) & Chr(Asc(strChar) + 1) & Mid(strString, lngI + 1, lngLenString)
Exit For
End If
Next lngI
IncrementString = strString
Exit Function
End Function
Apparently it is not working like it should. It increases the letter, but twice! (i , i , j , j , etc.)
Description textbox (for Table2 Record ) has as default value:
=IncrementString(DLast("[SeqNo]","[table2]"))
But like I said it increases the number by doing it double. I also have to start the process manually by entering an "a".
Neither the function nor the calling code presently allows for the "A##_" prefix. If you really MUST save this prefix to Table2, code would have to be adjusted to deal with it. As is, suggest not saving the "A##" group identifier as a prefix in Table2. Use a query that joins tables on PK/FK fields to retrieve related data for export.
The DLast() search must account for the "A##" group identifier because the sequence is repeated for each group.
Unfortunately, trying to set a DefaultValue property with a dynamic parameter dependent on main form ID is impractical. For one thing, subform loads before main form so the default value cannot be built since the main form data and controls are not available. Also, when the main form is moved to a new record, again there is no data for the default value to build with. The result is error displays for the control on new record row.
Use PK/FK fields for the search.
Code in subform Current event to call your incrementing function:
If Me.NewRecord And Not IsNull(Me.Parent.ReferenzNR) Then
Me!SerienBezeichnung = IncrementString(Nz(DLast("SerienBezeichnung", "tbl_GrundminenSerie", "ID_FK=" & Me.Parent.ReferenzID), ""))
End If
Be aware that DLast(), even though working now, could eventually fail because records do not have inherent order. An alternative would likely involve a recordset or nested domain aggregate. Example tested in VBA Immediate Window:
?DMax("SerienBezeichnung","tbl_GrundminenSerie","ID_FK=5 AND Len([SerienBezeichnung])=" & DMax("Len([SerienBezeichnung])","tbl_GrundminenSerie","ID_FK=5"))
Or if you feel autonumber PK can be depended on to always be increasing (which has always been my observation although there is no guarantee with autonumber):
?DLookup("SerienBezeichnung","tbl_GrundminenSerie","ID_FK=5 AND SerienID=" & DMax("SerienID","tbl_GrundminenSerie","ID_FK=5"))
Consider the following VBA function:
Function IncAlpha(ByVal strA As String, ByVal lngI As Long) As String
If lngI <= 0 Then
IncAlpha = strA
ElseIf strA = vbNullString Then
IncAlpha = IncAlpha("a", lngI - 1)
Else
lngI = lngI + Asc(Right(strA, 1)) - 97
IncAlpha = IncAlpha(Left(strA, Len(strA) - 1), lngI \ 26) & Chr(97 + lngI Mod 26)
End If
End Function
Supplied with a lowercase alphabetical string, this recursive function will increment the string by the supplied long integer argument, with z incrementing to aa, az incrementing to ba and so on.
Supplied with an empty string (""), the above function will return a.
?IncAlpha("", 1)
a
?IncAlpha("", 26)
z
?IncAlpha("", 27)
aa
?IncAlpha("", 42)
ap
?IncAlpha("", 314159)
qvsa
With this function, the suffix may therefore be calculated using:
<prefix> & IncAlpha("", DCount("[SeqNo]","[table2]") + 1)
Or to account for multiple prefixes:
<prefix> & IncAlpha("", DCount("SeqNo","table2","SeqNo like '" & <prefix> & "*'") + 1)

How to set custom ID field?

I have autonumber field in MS Access.
Here, it's starting with 1, 2, 3,…
But I want to enumerate numbers starts, with
2017ICLAA001, 2017ICLAA002, 2017ICLAA003,…
How to do that?
Simply type "2017ICLAA"000 into the ID field's Format Property
Should be able to figure out what you want with this since "2017...." is not always going to be the same and if you change it then it will jack up your database.
Example of Year-Number output: 17-0001
When the year changes the number auto resets to 1, because it checks the date then the number value which is incremental from 1 to 9,999 each year. You can delete records and it won't affect numbering since it always checks for the largest integer based on the current year, which is defined by your computers time/clock.
Must have the following columns: [AutonumberID] [DateCreated] [ColumnForYear-Number]
You should set the "[DateCreated]" column's "Default Value" in the Table's DesignView to "=Date()" (without quotes) so a date is added automatically when creating a record.
Add the following to your form's [Event Procedure] BEFOREINSERT otherwise if you update content in the record later (BeforeUpdate) it WILL change the record number everytime a change is made. You've been warned!
Do not use the date of a "[Last Modified]" type of column otherwise you will regret it in the future if you change/update anything in the record when the year changes and edits are made (think about it). Ensure you have a dedicated "[DateCreated]" column that doesn't change after inserting/adding the record no matter what year you decide to make any changes.
Here is the code:
Option Compare Database
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim vLast As Variant
Dim iNext As Integer
vLast = DMax("[ColumnForYear-Number]", "[Table]", "[ColumnForYear-Number] LIKE '" & _
Format([txtDateCreated], "yy\*\'"))
If IsNull(vLast) Then
iNext = 1
Else
iNext = Val(Right(vLast, 4)) + 1
End If
Me![ColumnForYear-Number] = Format([txtDateCreated], "yy") & "-" & Format(iNext, "0000")
End Sub
To get more than 9,999 records in one year change the number 4 in Val(Right(vLast, 4)) to a larger integer, then change the zeros in Format(iNext, "0000") to reflect the number of placeholders. The number 4 and there are four zeros. The same thing applies to the year, just change anywhere there is "yy" to "yyyy" for a four digit year. When making changes ensure the data type for the table's field/column can accept the total characters to be calculated or it will chop off any excess characters. Default is usually 255 characters for text however if your's says 8 characters are allowed for the [ColumnForYear-Number] and you are trying to add 9 or more then you will get frustrated troubleshooting a simple problem. Just FYI.
"[txtDateCreated]" is where the actual date entry exists and not the same as "[DateCreated]" which is the column name, unless you named your label that under the "Other" tab in Property Sheet. In other words columns are [columnname] and the textbox area where values are added/changed/viewed in FORMS should be labeled [txtcolumnname] (minus the brackets of course).
Additional options that are already configured into the format you request are listed in the next response (see below).
Since I had some more time on my hands I decided to answer your question more directly with a couple of options. My assumptions are: (1) You want the year 2017 to change automatically and (2) a prefix you define ICLAA followed by (3) an incremental number 001 that resets with each new year and (4) this is for a form with entry boxes (hence [txt...]).
Table Columns Required:
[AutoNumber] <=Not used here, it's just to show it still exists
[Column4UniqueValue] set the data type to Short Text and ensure your columns field size is set to 12 or more otherwise it will not work and will kick an error.
[DateCreated] set to Date/Time with format as General Date default value set =Date(), set Show Date Picker to Never for good measure, and set Locked value to Yes so user cannot change\override the value in the form. Note: this column [DateCreated] is not required if you decide to go with option two (2) listed below.
After you created the columns above in your table go to your form and add the new fields onto the form, click inside the newly added text field box and set its Other name as txt.... , then go into VBA Code Builder [Alt+F11] and add the code from either option one or option two.
Option One (with DateCreated field):
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim Prefix As String
Dim vLast As Variant
Dim iNext As Integer
Prefix = "ICLAA"
vLast = DMax("[Column4UniqueValue]", "[tblSource]", "[Column4UniqueValue] LIKE '" & Format([txtAreaOfDateCreated], "yyyy\*\") & Prefix & "*'")
If IsNull(vLast) Then
iNext = 1
Else
iNext = Val(Right(vLast, 3)) + 1
End If
Me![txtAreaOfColumn4UniqueValue] = Format([txtAreaOfDateCreated], "yyyy") & Prefix & Format(iNext, "000")
End Sub
Option Two (without DateCreated field):
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim Prefix As String
Dim vLast As Variant
Dim iNext As Integer
Prefix = "ICLAA"
vLast = DMax("[Column4UniqueValue]", "[tblSource]", "[Column4UniqueValue] LIKE '" & Format(Date, "yyyy\*\") & Prefix & "*'")
If IsNull(vLast) Then
iNext = 1
Else
iNext = Val(Right(vLast, 3)) + 1
End If
Me![txtAreaOfColumn4UniqueValue] = Format(Date, "yyyy") & Prefix & Format(iNext, "000")
End Sub
Your end results will look exactly like this 2017ICLAA001 and auto increment each year starting from one. Test it by creating a few records then change your computer's date/time clock to a later or earlier year and add another record. It should change with the year and when the year changes it will auto increment to the next highest value for that year. You can test this by toggling the computer year back and forth just to watch the values remain consistent when you add new records.

access VBA how to remove duplication from Collection

how do I remove duplication of objects in a Collection? This is what I tried:
dim unique_students as Collection
dim no_duplicate_student as cls_Student
dim no_duplication as boolean
For Each student as cls_Student In list_Student 'list_Students = original unsorted collection
no_duplication = True
Dim s As cls_Student
For Each s In unique_students
If s.name = student.name Then
no_duplication = False 'Duplication found
Exit For
End If
next s
If no_duplication Then
'Inserted into new sorted collection if no values matches that of the sorted collection
Set no_duplicate_student = New clsOverlap
no_duplicate_student.name = student.name
unique_students.Add no_duplicate_student
End If
Next student
This however still takes a long time (if list_Student.Count > 5000, then it'll take 30min+ to run). Is there a more efficient way (if possible, decrease time complexity) of removing duplication in a Collection?
Add the student names to a dictionary, which has the .Exists method to check if an item is already in the dictionary.
You can get some ideas from CollectionToDictionary in Collection And Dictionary Procedures
Something like this in your For Each student loop:
If Dict.Exists(Key:=student.name) Then
' is duplicate!
Else
Dict.Add Key:=student.name, Item:=student.name
' you could also do Item:=student if you want the de-duplicated list in a dictionary
End If
The inner loop is not needed. The function will probably run almost instantaneously.
I usually use a dictionary like what Andre451 suggested. Alternatively you could use an ArrayList like this. I'm not sure if there's much of a performance difference between the two but this method also produces a sorted list if that's desirable. The dictionary though can carry key/value pairs, so it just depends on what you're going after.
Sub Demo()
Set AL = CreateObject("System.Collections.ArrayList")
AL.Add "A"
AL.Add "B"
AL.Add "A"
AL.Add "A"
AL.Add "C"
'Sorting allows sequential comparisons to determine uniqueness
'You could also do something similar to the dictionary method with ArrayList.Contains
'but the evluation of ArrayList.Contains runs slower than this
AL.Sort
For i = 0 To AL.Count - 2
If AL(i) <> AL(i + 1) Then
'Prints unique values
Debug.Print AL(i)
End If
Next
If AL(i) <> AL(i - 1) Then
'Prints last value if unique by comparing to one before it
Debug.Print AL(i)
End If
End Sub
Edit: After testing I confirmed that the dictionary method is about twice as fast at 7.7 seconds versus 13 seconds per million. However, at the OP count of 5000 the difference is only 40 vs 80 ms.
Testing Code Here...
Public Declare Function GetTickCount Lib "kernel32.dll" () As Long
Sub DictionaryDemo()
Set D = CreateObject("Scripting.Dictionary")
Set AL = CreateObject("System.Collections.ArrayList")
For i = 0 To 10 ^ 6
AL.Add Round(Rnd * 10, 0)
Next
Start = GetTickCount
For i = 0 To AL.Count - 1
If Not (D.Exists(AL(i))) Then
D.Add AL(i), ""
Debug.Print AL(i)
End If
Next
Debug.Print GetTickCount - Start
End Sub
Sub ArrayListDemo()
Set AL = CreateObject("System.Collections.ArrayList")
For i = 0 To 10 ^ 6
AL.Add Round(Rnd * 10, 0)
Next
'Sorting allows sequential comparisons to determine uniqueness
Start = GetTickCount
AL.Sort
For i = 0 To AL.Count - 2
If AL(i) <> AL(i + 1) Then
'Prints unique values
Debug.Print AL(i)
End If
Next
If AL(i) <> AL(i - 1) Then
'Prints last value if unique by comparing to one before it
Debug.Print AL(i)
End If
Debug.Print GetTickCount - Start
End Sub
Edit Again: Ok, so I find this very interesting. What's most important appears to be the actual type itself. So for example, the testing above creates an ArrayList from which unique values are to be derived. If this is changed to a basic integer array Dim AL(10 ^ 6) As Integer, then the time is slashed from 7.7 to 0.8 seconds. Likewise, the ArrayList method can be slashed from 13 seconds down to 0.5 seconds simply by adding the line A = AL.ToArray after the sorting operation and looping through the array A instead.
This makes sense, since the memory allocation for arrays allows them to be processed really quick. It's also why some people prefer to create their own sorting and uniqueness algorithms rather than go with a less efficient but easy to use method employing a Dictionary or ArrayList as originally suggested here. The dictionary and ArrayLists are still powerful tools and, as mentioned above, they can still extract unique values from a 1 million length in a fraction of a second, but it's worth noting that when it comes to raw efficiency a simple array is wicked fast at looping.
The code below will extract unique values from a 1 million length array in about 0.3 seconds. It's not much different than the OP, but it's a lot more efficient. This is because looping through a collection is horribly slow, not because there was anything inefficient with the basic strategy. Also, notice that the efficiency will decrease as the number of unique values increases (this test only used the 10 unique of 1-10).
Sub ArrayDemo()
Dim A(10 ^ 6) As Integer
Dim B(10) As Integer
For i = 0 To 10 ^ 6
A(i) = Round(Rnd * 10, 0)
Next
Start = GetTickCount
k = 0
For i = 0 To 10 ^ 6
For j = 0 To k
If B(j) = A(i) Then GoTo nxt
Next
B(k) = A(i)
Debug.Print B(k)
k = k + 1
nxt:
Next
Debug.Print GetTickCount - Start
End Sub

How to insert particular columns of an XLS into MS SQL Server table?

I have an Excel spreadsheet of about 1000 rows and about 15 columns. What I would like to do is to import this data into a table, but selectively. I want data from Row 5(say) onwards till about 5 rows from the end of the sheet. This is because the number of rows may vary, but I am sure that I will not need the last 4-5 rows irrespective of the number of rows in the spreadsheet. Additionally, I would like to insert only a few columns, as, Col1-Col5, Col7-Col9, and Col12-Col15. Is there one command/sequence of commands that I can use to achieve this? Please let me know ASAP. Thanks a lot!
The code down there creates a file with SQL instructions based on what's in your xls. You just have to add a Macro, paste it, and change a few things (add a while to fill the ColFields Collection with the title line where the column names must match the table field names, declare what's not, give a value to fileName...).
Then execute the Macro and you'll have a file with all the insert you want, then you'll just have to execute this file on your base.
Sub Macro1()
Dim NbOfLines = Worksheets(Sheet1).Range("A65536").End(xlUp).Row - 5 'Not the 5 last lines
Dim ColFields As New Collection 'Do a while on the title line to fill the collection with wanted columns titles (do not add ignored columns)
Dim StartSql As String
StartSql = "INSERT INTO " + TableName + "("
For Each loopField In ColFields
StartSql = StartSql + loopField + ","
Next
StartSql = Left(StartSql, Len(StartSql) - 1)
StartSql = StartSql + ") SELECT "
Dim Value As String
For i = 1 To NbOfLines
Sql = ""
j = 1
For Each loopField In ColFields
Value = Worksheets(SheetName).Cells(i, j).Value
Sql = Sql + IIf(Value = "", "NULL", "'" + Replace(Value, "'", "''") + "'") + ","
j = j + 1
Next
Sql = Left(Sql, Len(Sql) - 1)
Sql = StartSql + Sql + vbCrLf
Call WriteLine(Sql, FileName)
Next
End Sub
Public Sub WriteLine(Ligne As String, FileName As String)
Open FileName For Append As #1
Print #1, Ligne
Close
End Sub
edit : I know it's not the best method (nor the most beautiful one), I gave it to you cos' I used it a few weeks ago to import data from a DB to another (but I needed to do it only once, not everyday).
I also know there is a way to do it with an OpenRowSet you're right about it, but I just don't know how (I'll go often on this page wishing someone'll teach me).
Finally, I encourage you to read this page : A Blog Page With A Solution
(You'll find the great procedure 'uftReadfileAsTable' here : The Procedure Code)
Good Luck!