My goal: to compare the filenames in a directory with the names in a spreadsheet. If there is a match, then I wish to append the corresponding account number of that name to the filename.
I have used the dir command to retrieve all of the filenames in a directory, then pasted the list into a column in the Excel spreadsheet.
I now have 4 columns: Account number, LastName, FirstName, and filename. The main problem here is that the filenames are inconsistent. They're in the form of "lastname, firstname date", but they vary in the forms of "Smith, John 010112", "Smith, J. 010112", "Smith J 010112". This means that when it comes to the first name, I'll only be comparing the first letter of the string.
So essentially, for each filename I need to check the lastname against the lastname column. If a match is found, then I need to check the first letter of the filename's firstname against the first letter of the firstname in the same row as the matching lastname. If this is also a match, then I need to grab the account number in that row and append it to the filename.
How could I do this? I'm pretty new to Excel functions, but I do have a little experience with coding in Java and C from some college classes.
Since you already have the filenames in a column, you can solve the rest using an Excel Formula
=IF(SEARCH(B2&", "&LEFT(C2,1),D2,1)>0,A2&"-"&D2,IF(SEARCH(B2&" "&LEFT(C2,1),D2,1)>0,A2&"-"&D2,""))
This formula will hold true for both Jake Smith and John Smith.
Snapshot
Note:
A2&"-"&D2 part in the formula adds the Ac. No to the Old Filename. If you want Ac. No to be added in the end then change the above to D2&"-"&A2
Well dealling with inconsistent strings can be tricky. Here's a function that can determine the matching last name, and intial of the first name, provided the string pattern doesn't vary outside of your example. Add it to a module, then you can access it by typing in the formula =AppendFileName into a cell.
Public Function AppendFileName(ByVal LName As String, ByVal FName As String, ByVal FileName As String, ByVal AccN As String) As String
If LName = Left(FileName, Len(LName)) Then
If Mid(FileName, Len(LName) + 1, 1) = "," Then 'Check if the string contains a comma
If Mid(FileName, Len(LName) + 3, 1) = Left(FName, 1) Then
AppendFileName = FileName & " " & AccN
End If
Else 'If no comma then assume just one space
If Mid(FileName, Len(LName) + 2, 1) = Left(FName, 1) Then
AppendFileName = FileName & " " & AccN
End If
End If
End If
If AppendFileName = "" Then AppendFileName = False
End Function
You can create a loop around this code to go through all the files and names and automate with the dir function, eg.
Dim x as integer, DirFile as string
DirFile = Dir(Path)
Do While DirFile <> ""
x = x + 1 'To track how many files, and to assign variables as in below line of code
'Set each string variable like FName = Range("A1").offset(x,0).value
'Then assess the the names and file names with the If statements above
'Do something with appended FileName
DirFile = Dir
Loop
Hope this helps.
Related
I have a table named 'odonto' and it has the fields code (autoincremental), history, surnames and names. I need to generate the code so that it autogenerates the HISTORY obtaining the first letter of the last name which will then have to be concatenated with consecutive numbers for each letter. That is to say that if we have four "FLORES" and a "MENDOZA" in the register it shows in a text box the next samples:
F001
F002
F003
F004
M001
...
Also I need to keep in mind that if a record is deleted it will be replaced by incrementing it again.
I did it and it functions for the asigning value, but it doesn't replace the deleted one if it.
Private Sub APELLIDO_AfterUpdate()
Dim MyStr
MyStr = Left([APELLIDO], 1)
Me.LETRA = MyStr
If IsNull(Me.HISTORIA) Then
Me!HISTORIA = ((MyStr) & "0000" & ([Cant] + 1))
Else
HISTORIA = Me.HISTORIA
End If
Me.Refresh
End Sub
Please your help.
I am looking for a function that will extract all the information between the 2nd and 3rd comma.
[DropOffAddress] = "Hotel, 1234 Johnson St, Minneapolis, MN 55449"
I am looking to extract just "Minneapolis" from the string above.
If it is less complicated, just extracting "Minneapolis, MN 55449" is workable.
I am using a query to display the information and I know the info I will always be between the second and third comma in the field [DropOffAddress]
Thanks
You can in VBA code use this:
dim strResult as string
strResult = split(strSourceString,",")(2)
So split is zero based, and hence "2" will get us the 3rd token out of the string delimited by ",".
You can't however use VBA split() function in sql query, but you can use it in code as per above.
If you need this in a query?
Then in a standard code module, then place this function.
Public Function MySplit2(v As Variant, ix As Integer) As String
MySplit = ""
If IsNull(v) Then Exit Function
If v = "" Then Exit Function
Dim vBuf As Variant
vBuf = Split(v, "|")
If ix > UBound(vBuf) Then Exit Function
MySplit = vBuf(ix)
End Function
Now, in a sql query, say one column was UserName (first name,LastName)
SELECT id, MySplit([UserName],0) as FirstName,
MySplit([UserName],1) as LastName, City, State from tblCustomers
I have a form that adds new users. I'm trying to auto generate the username, which needs to be unique. I have a function checkUsername that takes the string passed and checks the db table to see if that username exists. It returns false if the username exists and true if not.
What I'm trying to do is if the username already exists then add a number on to the end and check again. I want to keep looping until a unqiue username is found. Heres my attempt at a loop below, however its returning usernames that already exist. Also I prefer it to increment the number rather than just adding it to the end. Currently the pattern ends up being username1, username12, username123.
'Generate username
Dim Username As String
Username = generateUsername(LCase(Left(FirstName, 1) & LastName))
Function generateUsername(Username As String) As String
Dim i As Integer
i = 1
Do While checkUsername(Username)
If checkUsername(Username) Then
Exit Do
Else
Username = Username & i
i = i + 1
End If
Loop
generateUsername = Username
End Function
What I would do is, when the username exists already (see Andre's answer for the code that will accomplish this a different way):
check what the previous "i" number was, as a string, to see how many characters I need to cut off the end of username
set username equal to a substring of username, which will cut off the last X characters (X being the number of characters the previous "i" was)
add the new "i" to the end username
That will solve your naming issue.
For your issue of looking for unique names, no one will be able to help with that until we can see what the code looks like for the "checkUsername" function. Make sure that that function is returning the value you are expecting, first. I suspect the problem is in there.
EDIT:
I also don't understand why you have an "If/Else" statement in your loop. You already determined that it was true. See below for simplified version (again, assuming I got the code right for VB...I usually do it in C#):
Do While Not checkUsername(NewName)
NewName = Username & i
i = i + 1
Loop
I assume checkUsername() returns true if the username exists?
Then your If condition is wrong - you want to exit if it doesn't exist.
Your loop gets clearer if you use two variables:
Function generateUsername(origUsername As String) As String
Dim i As Integer
Dim Username As String
i = 1
Username = origUsername
Do While checkUsername(Username)
' If Not checkUsername(Username) Then
' Exit Do
' Else
Username = origUsername & i
i = i + 1
' End If
Loop
generateUsername = Username
End Function
Edit: as pointed out by Joel, the additional checkUsername() in the loop isn't needed. Since it probably involves a DLookup or similar, it is actually harmful to performance.
I commented it out above.
Sorry, but this is the corrected version!
Change your code to this instead:
Dim Username As String
Username = generateUsername(LCase(Left(FirstName, 1) & LastName))
Function generateUsername(Username As String) As String
Dim NewName as String
Dim i As Integer
i = 1
NewName = Username
Do While checkUsername(NewName)
If checkUsername(NewName) Then
Exit Do
Else
NewName = Username & i
i = i + 1
End If
Loop
generateUsername = NewName
End Function
GoodDay to you all!
I am working on an excel project and I am looking for some help. I don't mind whether this is solved via a formula or a script.
To begin with I will provide the big picture. I have a whole bunch of SQL Queries that call on various fields from different locations. These field titles have now changed. I would like to update the SQL Queries with the new names of the fields. As such, I was going to copy all the queries into an excel spreadsheet and then lookup the field names in the string and replace them with the new field names from a table in another sheet. The problem is that there is approximately 10 field names per query that need replacing.
So this is what I was thinking. Essentially, if I have a string in cell A1 with the words: "We are the very best". For every word that exists in the string I would like to check if it exists in a table in another sheet. If the word exists in the table, replace it. If not then move onto the next word. Continue for every word in the cell.
Any help that can be provided is very much appreciated. Thanks in advance!
Consider:
Sub FixIt()
Dim r As Range, A As Range
Dim s1 As Worksheet, s2 As Worksheet
Set s1 = Sheets("Sheet1")
Set s2 = Sheets("Sheet2")
Set A = s1.Range("A:A").Cells.SpecialCells(xlCellTypeConstants)
For Each r In A
v = " " & r.Value & " "
For j = 1 To 10
oldv = " " & s2.Cells(j, 1).Text & " "
newv = " " & s2.Cells(j, 2).Text & " "
v = Replace(v, oldv, newv)
Next j
r.Value = Trim(v)
Next r
End Sub
In this example the replacement table is in Sheet2, cells A1 thru B10...............I pad with "spaces" to insure whole word replacement and to avoid the need to Split and Join.
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!