I use Foxit Phantompdf, the complete version and ACCESS.
In our program, we have to save multiple pdf files, some of them should be merged in single files when saved.
Here is the code I use;
Dim phApp As PhantomPDF.Application
Dim n1 As String
Dim n2 As String
n1 = "c:\Temp\F3769-190136-GROUPE OCÉAN.pdf"
n2 = "c:\Temp\f3769-190136-GROUPE OCÉAN- facture.pdf"
Set phApp = CreateObject("PhantomPDF.Application")
Dim phCreator As PhantomPDF.Creator
Set phCreator = phApp.Creator
***'Call phCreator.CombineFiles("c:\Temp\F3769-190136-GROUPE OCÉAN.pdf|c:\Temp\f3769-190136-GROUPE OCÉAN- facture.pdf", "c:\Temp\F3769-190136-GROUPE OCÉAN.pdf", COMBINE_ADD_CONTENTS)***
Call phCreator.CombineFiles("""c:\Temp\" & n1 & "|'" & n2 & """" & ", " & """c:\Temp\F3769-190136-GROUPE OCÉAN.pdf"""" &", COMBINE_ADD_CONTENTS)
phApp.Exit
When I try it with the complete files names (in bold) the code works perfectly.
However, when I try to use variables, I get a
"Argument not optional"
error.
Can somebody help me ?
Thanks
Your string definitions in call line is incorrect.
You have defined n1 and n2 with the c:\temp already, and in your string conversion you add this again. I do not know if this is the route cause to your issue.
Furthermore I do not know the actual needed syntax for this phcreator.combine()
But is it not possible using only:
call pHcreator.combine(n1 & "|" & n2, …
The 'Argument not option' might imply you should add another input to your pHcreator, I would guess it could have something to do with FOXIT's combine function page settings. Try adding a input variable integer at the end of the function maybe?
But the fact that it works when writing strings in clear text would maybe suggest that the string manipulations is not correct?
I'm not a vba professional, but interested in the outcome, working myself with Foxit and also want to combine with vba. I'm currently not using version 9 som I seem to be out of luck, and only upgrading it I know what I want to do is possible.
I tried it, but got the same error message. So I took advantage of the fact that the function works when the file names are in plain text. I copied the files to be merged in a temporary folder and rename them. The renamed files are the then used in the merge function. It works perfectly, but Foxit adds a table of content page, and I don't know, yet, how to remove it. Here is my solution:
Private Sub Command4_Click()
Dim addi As String 'file to be merged to main file
Dim princi As String 'main file
Dim phApp As PhantomPDF.Application
'A temporary folder, in this case c:\t2, should be present
'In this example c:\Temp is the working folder
addi = "c:\Temp\filetomerge.pdf" 'full path of file to be merged
princi = "c:\Temp\mainfile.pdf" 'full path of main file
'fadd,pdf and fmain.pdf are the temporay files used in Foxit's function
FileCopy addi, "c:\t2\fadd.pdf" 'temporary file to be merged in temporary folder
FileCopy princi, "c:\t2\fmain.pdf" 'temporary main file in temporary folder
'Merge action
Set phApp = CreateObject("PhantomPDF.Application")
Dim phCreator As PhantomPDF.Creator
Set phCreator = phApp.Creator
Call phCreator.CombineFiles("c:\t2\fmain.pdf|c:\t2\fadd.pdf", "c:\t2\fmain.pdf", COMBINE_ADD_CONTENTS)
phApp.Exit
'Save merged file in working folder under main file name
Kill princi
FileCopy "c:\t2\fmain.pdf", princi
'delete temporary files
Kill "c:\t2\fadd.pdf"
Kill "c:\t2\fmain.pdf"
End Sub
I am creating a script that will contain variables that need to be set by the user. I created an ini file where those variables can be defined by the user without having to mess with the script itself. I need the VBS script to be able to read the file and create a variable based on the first part of the line and then set the value of that variable based on the second part of that line.
The ini file looks something like this
path=C:\users\whatever
filename=whatever.txt
FileTypes=txt,doc,mp3,etc
In a batch file, this is easy, you can simply do:
for /f "delims=" %%x in (config.ini) do (set "")
I would love if there is an equally simple answer in VBS, but here is what I have (working)
filename = "config.ini"
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile(filename)
Do Until f.AtEndOfStream
LineArray = Split(f.ReadLine , "=")
Select Case LineArray(0)
Case "path"
path = LineArray(1)
Case "filename"
fname = LineArray(1)
Case "FileTypes"
FileTypes = LineArray(1)
End Select
Loop
f.Close
This works, but I essentially had to rename my variables myself, and the script is more difficult to maintain and not as efficient.
It would be nice if I could replace the case statement with something more like
DIM "LineArray(0)"=LineArray(1)
and have VBS recognize that LineArray(0) should be defined as a new variable using the value of LineArray(0) as the name of the variable.
Is there a way to do this in VBS?
Execute (or ExecuteGlobal) will do what you want with the input you described. I would advise caution, though, because these statements will not only define variables, but execute any code passed into them. Using a dictionary is a safer approach:
Set ini = CreateObject("Scripting.Dictionary")
Do Until f.AtEndOfStream
line = f.ReadLine
If InStr(line, "=") > 0 Then
arr = Split(line, "=", 2)
ini(Trim(arr(0))) = arr(1)
End If
Loop
WScript.Echo ini("path")
Particularly if you want to handle actual INI files, which may consist of several sections (and also contain comments):
[section1]
foo = "something"
bar = 42
[section2]
;this is a comment
foo = "something"
baz = 23
I wrote such an INI parser myself a couple years ago. You can find it on my blog.
I figured it out. The answer is Execute. The simple line I needed was:
Execute(LineArray(0) + " = " + "LineArray(1)")
This is my sample file
#%cty_id1,#%ccy_id2,#%cty_src,#%cty_cd3,#%cty_nm4,#%cty_reg5,#%cty_natnl6,#%cty_bus7,#%cty_data8
690,ALL2,,AL,ALBALODMNIA,,,,
90,ALL2,,,AQ,AKNTARLDKCTICA,,,
161,IDR2,,AZ,AZLKFMERBALFKIJAN,,,,
252,LTL2,,BJ,BENLFMIN,,,,
206,CVE2,,BL,SAILFKNT BAFSDRTHLEMY,,,,
360,,,BW2,BOPSLFTSWLSOANA,,,,
The problem is for #%cty_cd3 is a standard column(NOT NULL) with length 2 letters only, but in sql server the record shifts to the other column,(due to a extra comma in btw)how do i validate a csv file,to make sure that
when there's a 2 character word need to be only in 4 column?
there are around 10000 records ?
Set of rules Defined !
Should have a standard set of delimiters for eachrow
if not
Check for NOT NULL values having Null values
If found Null
remove delimiter at the pointer
The 3 ,,, are not replaced with 2 ,,
#UPDATED : Can i know if this can be done using a script ?
Updated i need only a function That operates on records like
90,ALL2,,,AQ,AKNTARLDKCTICA,,, correct them using a Regex or any other method and put back into the source file !
Your best bet here may be to use the tSchemaComplianceCheck component in Talend.
If you read the file in with a tFileInputDelimited component and then check it with the tSchemaComplianceCheck where you set cty_cd to not nullable then it will reject your Antarctica row simply for the null where you expect no nulls.
From here you can use a tMap and simply map the fields to the one above.
You should be able to easily tweak this as necessary, potentially with further tSchemaComplianceChecks down the reject lines and mapping to suit. This method is a lot more self explanatory and you don't have to deal with complicated regex's that need complicated management when you want to accommodate different variations of your file structure with the benefit that you will always capture all of the well formatted rows.
You could try to delete the empty field in column 4, if column no. 4 is not a two-character field, as follows:
awk 'BEGIN {FS=OFS=","}
{
for (i=1; i<=NF; i++) {
if (!(i==4 && length($4)!=4))
printf "%s%s",$i,(i<NF)?OFS:ORS
}
}' file.csv
Output:
"id","cty_ccy_id","cty_src","cty_nm","cty_region","cty_natnl","cty_bus_load","cty_data_load"
6,"ALL",,"AL","ALBANIA",,,,
9,"ALL",,"AQ","ANTARCTICA",,,
16,"IDR",,"AZ","AZERBAIJAN",,,,
25,"LTL",,"BJ","BENIN",,,,
26,"CVE",,"BL","SAINT BARTH�LEMY",,,,
36,,,"BW","BOTSWANA",,,,
41,"BNS",,"CF","CENTRAL AFRICAN REPUBLIC",,,,
47,"CVE",,"CL","CHILE",,,,
50,"IDR",,"CO","COLOMBIA",,,,
61,"BNS",,"DK","DENMARK",,,,
Note:
We use length($4)!=4 since we assume two characters in column 4, but we also have to add two extra characters for the double quotes..
The solution is to use a look-ahead regex, as suggested before. To reproduce your issue I used this:
"\\,\\,\\,(?=\\\"[A-Z]{2}\\\")"
which matches three commas followed by two quoted uppercase letters, but not including these in the match. Ofc you could need to adjust it a bit for your needs (ie. an arbitrary numbers of commas rather than exactly three).
But you cannot use it in Talend directly without tons of errors. Here's how to design your job:
In other words, you need to read the file line by line, no fields yet. Then, inside the tMap, do the match&replace, like:
row1.line.replaceAll("\\,\\,\\,(?=\\\"[A-Z]{2}\\\")", ",,")
and finally tokenize the line using "," as separator to get your final schema. You probably need to manually trim out the quotes here and there, since tExtractDelimitedFields won't.
Here's an output example (needs some cleaning, ofc):
You don't need to entry the schema for tExtractDelimitedFields by hand. Use the wizard to record a DelimitedFile Schema into the metadata repository, as you probably already did. You can use this schema as a Generic Schema, too, fitting it to the outgoing connection of tExtractDelimitedField. Not something the purists hang around, but it works and saves time.
About your UI problems, they are often related to file encodings and locale settings. Don't worry too much, they (usually) won't affect the job execution.
EDIT: here's a sample TOS job which shows the solution, just import in your project: TOS job archive
EDIT2: added some screenshots
Coming to the party late with a VBA based approach. An alternative way to regex is to to parse the file and remove a comma when the 4th field is empty. Using microsoft scripting runtime this can be acheived the code opens a the file then reads each line, copying it to a new temporary file. If the 4 element is empty, if it is it writes a line with the extra comma removed. The cleaned data is then copied to the origonal file and the temporary file is deleted. It seems a bit of a long way round, but it when I tested it on a file of 14000 rows based on your sample it took under 2 seconds to complete.
Sub Remove4thFieldIfEmpty()
Const iNUMBER_OF_FIELDS As Integer = 9
Dim str As String
Dim fileHandleInput As Scripting.TextStream
Dim fileHandleCleaned As Scripting.TextStream
Dim fsoObject As Scripting.FileSystemObject
Dim sPath As String
Dim sFilenameCleaned As String
Dim sFilenameInput As String
Dim vFields As Variant
Dim iCounter As Integer
Dim sNewString As String
sFilenameInput = "Regex.CSV"
sFilenameCleaned = "Cleaned.CSV"
Set fsoObject = New FileSystemObject
sPath = ThisWorkbook.Path & "\"
Set fileHandleInput = fsoObject.OpenTextFile(sPath & sFilenameInput)
If fsoObject.FileExists(sPath & sFilenameCleaned) Then
Set fileHandleCleaned = fsoObject.OpenTextFile(sPath & sFilenameCleaned, ForWriting)
Else
Set fileHandleCleaned = fsoObject.CreateTextFile((sPath & sFilenameCleaned), True)
End If
Do While Not fileHandleInput.AtEndOfStream
str = fileHandleInput.ReadLine
vFields = Split(str, ",")
If vFields(3) = "" Then
sNewString = vFields(0)
For iCounter = 1 To UBound(vFields)
If iCounter <> 3 Then sNewString = sNewString & "," & vFields(iCounter)
Next iCounter
str = sNewString
End If
fileHandleCleaned.WriteLine (str)
Loop
fileHandleInput.Close
fileHandleCleaned.Close
Set fileHandleInput = fsoObject.OpenTextFile(sPath & sFilenameInput, ForWriting)
Set fileHandleCleaned = fsoObject.OpenTextFile(sPath & sFilenameCleaned)
Do While Not fileHandleCleaned.AtEndOfStream
fileHandleInput.WriteLine (fileHandleCleaned.ReadLine)
Loop
fileHandleInput.Close
fileHandleCleaned.Close
Set fileHandleCleaned = Nothing
Set fileHandleInput = Nothing
KillFile (sPath & sFilenameCleaned)
Set fsoObject = Nothing
End Sub
If that's the only problem (and if you never have a comma in the field bt_cty_ccy_id), then you could remove such an extra comma by loading your file into an editor that supports regexes and have it replace
^([^,]*,[^,]*,[^,]*,),(?="[A-Z]{2}")
with \1.
i would question the source system which is sending you this file as to why this extra comma in between for some rows? I guess you would be using comma as a delimeter for importing this .csv file into talend.
(or another suggestion would be to ask for semi colon as column separator in the input file)
9,"ALL",,,"AQ","ANTARCTICA",,,,
will be
9;"ALL";,;"AQ";"ANTARCTICA";;;;