I've made an application where users write stuff in Excel cells and that info is then printed to a .txt file.
The info is concatenated into a long string before printing it into the file.
The info is not stored in the Excel sheet. Every time you open the sheet, it loads the info from the .txt file into the different cells. If a user changes the content of a cell the info is then printed to the .txt file. Multiple people are working at the same time, changing the cells. Everyone has got their own version of the empty workbook, where the data loads when the workbook is opened. And when someone changes a cell, the data is printed to the .txt file and is then everyone who is working with the application is reading from the file and getting that cell updated with the new info.
Now, someone copied the content of a cell into another cell and hit Enter (which triggers the concatenation process and stores it into the .txt file) What happened was that all the info after the new info didn't get printed. So the last 30000 characters or so just got lost. I'm thinking the user accidentally copied a character with a special meaning like "Stop reading and print to file" or something. But does characters like that exists? Do you have any clue what might have happened?
This is the code that concatenates the string:
Line = ProjectsArray(0) 'Line is the long string that gets printed to the text file
ProjectsArray(ProjectsArrayPosition) = ProjectNumber 'ProjectsArray is string 'Line' but split into the different projects
'ProjectInfo is a specific project split into its different data points. (Every data point belongs to a Excel cell)
'ProjectsArrayPosition is the place in the array where the current Project lives.
'Every data point is joined with a chr(17) in between.
For i = 1 To UBound(ProjectInfo)
ProjectsArray(ProjectsArrayPosition) = ProjectsArray(ProjectsArrayPosition) & Chr(17) & ProjectInfo(i)
Next i
If UBound(ProjectsArray) > 0 Then
For i = 1 To UBound(ProjectsArray)
Line = Line & Chr(18) & ProjectsArray(i) 'Every project is joined with a chr(18) in between
Next i
End If
On Error GoTo NoPath
Open ProjectsFilePath For Output As #1
Print #1, Line
Close #1
On Error GoTo 0
Here's the code that opens the array:
On Error GoTo NoPath
Open ProjectsFilePath For Input As #1
Line Input #1, Line
Close #1
On Error GoTo 0
ProjectsArray = Split(Line, Chr(18))
For i = 1 To UBound(ProjectsArray)
If CInt(Left(ProjectsArray (i), 6)) = ProjectNumber Then
ProjectInfo = Split(ProjectsArray(i), Chr(17))
ProjectsArrayPosition = i
End If
Next i
Select Case ActiveCell.Address
Case "$N$11"
For i = 0 To UBound(ProjectInfo)
If Left(ProjectInfo(i), 1) = "B" then
ProjectInfo(i) = "B" & Sht.Range("N11").Value
End If
Next i
Case "$G$18"
For i = 0 To UBound(ProjectInfo)
If Left(ProjectInfo(i), 1) = "F" then
ProjectInfo(i) = "F" & Sht.Range("G18").Value
End If
Next i
Case "$M$20"
And so on and so on
End Select
The code above is loaded every time you press Enter.
Private Sub Workbook_Activate()
Application.OnKey "~", "EnterPress"
Application.OnKey "{ENTER}", "EnterPress"
End Sub
Related
I have a Microsoft project vba application where I want to copy a selection of tasks using the "marked" field to identify all of the predecessor tasks to a target task, identified as the "target" below. When I have traced the network back to include only incompleted tasks, control passes to a routine which uses DocumentExport to create a copied file and save it to a pdf. Then, using ActiveSheet.OLEObjects.add, take this PDF and copy to a specific excel Tab with the "A3" cell being the top/left corner for the file to be placed.
excerpts of my current code:
target = ActiveCell.Task
SaveFilePath = "C:\Macros\"
SaveFileName = SaveFilePath & "Target-" & target & ".pdf"
SaveFilePath = "C:\Macros\"
SaveFileName = SaveFilePath & "Target-" & target & ".pdf"
Application.FilePageSetupView Name:=".MarkedPred_View", allsheetcolumns:=True, BestPageFitTimescale:=True
Application.FilePageSetupPage Name:=".MarkedPred_View", Portrait:=False, PagesTall:=6, PagesWide:=1, PaperSize:=pjPaperLegal, FirstPageNumber:=False
StrHeader = "&18&B" & GetFontFormatCode("Calibri") & "Status Date=" & Format(ActiveProject.StatusDate, "mm/dd/yy") & " Task Name= " & SelTask.Name & " ID:" & SelTask.ID & " UID:" & SelTask.UniqueID
Application.FilePageSetupHeader Name:=".MarkedPred_View", Alignment:=pjCenter, Text:=StrHeader
Application.FilePageSetupLegend Name:=".MarkedPred_View", LegendOn:=pjNoLegend
DocumentExport SaveFileName, pjPDF, FromDate:=EarliestStart - 30, ToDate:=LFin + 30
xlsheet.Range("A3").Select
ActiveSheet.OLEObjects.Add(FileName:=SaveFileName, Link:=True _
, DisplayAsIcon:=False).Activate
If I set the Link property to false, the copy to excel does not happen
sbDeleteAFile (SaveFileName)
Sub DeleteAFile(ByVal FileToDelete As String)
IsFileOpen (FileToDelete)
SetAttr FileToDelete, vbNormal
Kill FileToDelete
End Sub
Function IsFileOpen(FileName As String)
Dim filenum As Integer, errnum As Integer
OutputStr = ("1587 - IsFileOpen - started for = " & FileName) 'added
Call Txt_Append(MyFile, OutputStr)
On Error Resume Next ' Turn error checking off.
filenum = FreeFile() ' Get a free file number.
' Attempt to open the file and lock it.
Open FileName For Input Lock Read As #filenum
Close filenum ' Close the file.
errnum = Err ' Save the error number that occurred.
On Error GoTo 0 ' Turn error checking back on.
' Check to see which error occurred.
Select Case errnum
Case 0
IsFileOpen = False
'Open (Filename)
' Error number for "Permission Denied."
' File is already opened by another user.
OutputStr = ("1587 - IsFileOpen - is NOT Open") 'added
Call Txt_Append(MyFile, OutputStr)
Case 70
IsFileOpen = True
' Another error occurred.
Case Else
OutputStr = ("1587 - IsFileOpen - IS Open") 'added
Call Txt_Append(MyFile, OutputStr)
Error errnum
End Select
End Function
"LFin" is the finish date of the target task, from which I am collecting all of its predecessors. I am using the finish date as the "Latest Finish" (LFIN) to bound the "ToDate" in the command.
The error appears with the "ActiveSheet.OLEObjects.Add (fileName:=SaveFilename, Link:=True _" command, where the PDF is opened and copied to the specified excel tab with cell "A3" being the point of the paste for the image.
I do not have any code to close the PDF in this snippet so I get an error when I try to delete an open file. I have seen lots of discussion on various boards where if a file is opened by another application, MS Project VBA cannot delete it as it does not have the handle to the file (??). If I manually close the PDF, close the error notification in the debugger and then press "Run/Continue" , the PDF is deleted and cycles back through the main routine, just like I want it to but I have to again close the newly created PDF, clear the dialog and select Run/Continue.
The only section of this code which does not work as desired (and is currently missing in this code) is having the ability to close the PDF after it has been copied to Excel as it is no longer needed. I have only seen very complicated code which gets the handle of the PDF and then allows you to close the specific file without affecting any other PDF files which may also be open and are not part of this process.
Does anyone have any ideas? I first started using CopyToClipboard, but this command only can copy 16 rows of MS Project schedule to the clipboard. Then, I tried ExportAsFixedFormat, but the FromDate and ToDate entries have no effect on the displayed image.
Using DocumentExport and Application.OLEObjects.Add allows me to copy unlimted pages of schedule to the clipboard and paste into an excel tab showing the desired dates only.This is the closest I have been able to come to get what I want the output to look like. I have been unable to find an associated command to Application.OLEObjects.Add command which I can use to close the PDF file created by the Application.OLEObjects.Add. It certainly makes sense that you want to open the PDF file so it can be copied to the Excel tab, but it is surprising there is not also an easy way to close that PDF file after it has served its purpose.
The question boils down to this:
The error appears with the "ActiveSheet.OLEObjects.Add
(fileName:=SaveFilename, Link:=True, DisplayAsIcon:=False).Activate" command, where the PDF is
opened and copied to the specified excel tab...
The reason the pdf file opens is that the code is telling it to. By using the Activate method on the OLEObject just added, it activates it--meaning in opens the pdf file.
The solution is to simply the OLEObjects.Add method to this:
ActiveSheet.OLEObjects.Add FileName:=SaveFileName
I have a text File named "amk.txt" which looks inside like:
Test Number 1234
sampleCounter 123
Time Speed[km\h]
1 12
2 13
3 14
4 15
I need to print the content to Excel Sheet by using VBA. I have a Function to read the content of the file and to save the content into an Array. The Array looks inside like this:
TestNumber1234
sampleCounter123
TimeSpeed[km\h]
112
213
314
415
My Problem is, that the array which saves the fileContent does not look like the inside of txt file.
So I have to questions:
makes it sense to save the file content to a array or to print it directly into the excel sheet?
If I want to save it into the array, why does the array not look like the text file?
I wrote two different Functions to save the file content into a array
First Function:
Public Function read_file_with_FSO(fileName)
Const ForReading=1
Set fileObject = CreateObject("Scripting.FileSystemObject")
Set file= fileObject.OpenTextFile(fileName, ForReading)
fileContentFSO=Split(f.readAll,vbNewline)
read_file_with_FSO=fileContentFSO
End Function
Second Function:
Public Function read_file(fileName)
index=0
Open fileName For Input as #1
Line Input #1, textline
fileContent(index)=textline
index=index+1
Loop
Close #1
read_file=fileContent
End Function
Try following code to load the file to excel:
Sub Load_text_file()
Dim strFilename As String, strLine As String, strSprt As String
Dim lngRows As Long
strFilename = Application.GetOpenFilename("Text files, *.txt") ' you may replace this with direct path to your file. NOTE there is no handler for "Cancel" button here - so there will be an error if you press it
Open strFilename For Input As #1
lngRows = 1
Do While Not EOF(1)
Line Input #1, strLine
ActiveSheet.Cells(lngRows, 1) = strLine ' !!! replace an ActiveSheet with your sheet's name
lngRows = lngRows + 1
Loop
Close #1
End Sub
Then go to Excel, select the copied data, go to Data tab, press the Text to Columns button. On the first step select "Delimited" and press next. On the second step - try selecting different delimiters, unless you see that Excel splits text to columns using one of them:
If you find delimiter in you file (usually it is the Tab, Comma or Semicolon) then you can add following code to the sub above:
With ActiveSheet ' !!! replace an ActiveSheet with your sheet's name
range(.Cells(1, 1), .Cells(lngRows - 1, 1)).TextToColumns Destination:=.Cells(1, 1), Tab:=True ' In my case the delimiter is Tab, so set it to true, when you start typing editor will suggest parameters. If you'd like to use other character - you will need to set also that char: other:=True, otherchar:="|"
End With
If this doesn't help - you may need to change your text file format or create some sub or function to get your text formatted properly in Excel.
Try the code, read comments, ask if something is not clear.
The array you have is each line in the file.
Since it's a text file with tabs you may be able to read & paste the contents all in to cell A1 and because of the tabs it will fill out across multiple lines and tab delimited columns.
Range("A1").Select
ActiveSheet.Paste
Or
Range("A1").PasteSpecial Paste:=xlPasteFormats
You can google how to use the VBA clipboard, to save what's already in the clipboard, set the file contents to clipboard, then do the paste command above and finally restore whatever the user previously had in their clipboard.
The 2nd screenshot looks like the VBEditor Watch window and that's showing each line as an array item. You could iterate through the array, using Split to get elements and in a nested loop lay them out.
Example - Source:
ID NAME TEXT
01 John Lore ipsum..
In this case all cells have format General and Lore ipsum.. text have format Text
And I want export this excel stylesheet to csv with comma separated and lore ipsum.. text with double quotes, something like this:
ID,NAME,TEXT
01,John,"Lore ipsum.."
Might not be exactly as asked, however this is what worked best for me:
Save the CSV in Excel normally (File > Save As > CSV (Comma separated))
Open a powershell window where the exported CSV is
Run this command (considering the CSV file was named "Book1.csv":
import-csv -path .\Book1.csv -Delimiter ";" | export-csv -path .\Book1_comma.csv -Delimiter ","
The following Microsoft article details the procedure you're looking for; http://support.microsoft.com/kb/291296 In the spirit of SO, I'll summarise here.
In Excel (I'm using 2003), navigate to Tools > Macro > Visual Basic Editor. That will launch the editor in a new window.
Next you want Insert > Module. In that window, paste the VB code, as follows:
Sub QuoteCommaExport()
' Dimension all variables.
Dim DestFile As String
Dim FileNum As Integer
Dim ColumnCount As Integer
Dim RowCount As Integer
' Prompt user for destination file name.
DestFile = InputBox("Enter the destination filename" _
& Chr(10) & "(with complete path):", "Quote-Comma Exporter")
' Obtain next free file handle number.
FileNum = FreeFile()
' Turn error checking off.
On Error Resume Next
' Attempt to open destination file for output.
Open DestFile For Output As #FileNum
' If an error occurs report it and end.
If Err <> 0 Then
MsgBox "Cannot open filename " & DestFile
End
End If
' Turn error checking on.
On Error GoTo 0
' Loop for each row in selection.
For RowCount = 1 To Selection.Rows.Count
' Loop for each column in selection.
For ColumnCount = 1 To Selection.Columns.Count
' Write current cell's text to file with quotation marks.
Print #FileNum, """" & Selection.Cells(RowCount, _
ColumnCount).Text & """";
' Check if cell is in last column.
If ColumnCount = Selection.Columns.Count Then
' If so, then write a blank line.
Print #FileNum,
Else
' Otherwise, write a comma.
Print #FileNum, ",";
End If
' Start next iteration of ColumnCount loop.
Next ColumnCount
' Start next iteration of RowCount loop.
Next RowCount
' Close destination file.
Close #FileNum
End Sub
Next you'll need to highlight the cells in your spreadsheet that you want to export. Once they've been selected, Run your macro against them. Specify a path to save your file to, and you're done.
Full credits to the author of the article at Microsoft, http://support.microsoft.com/kb/291296.
I'm reading multiple csv files into excel for some number crunching. The file reads appear to work with each excel column having the csv file name inserted for confirmation. Odd thing. Each csv file name is correctly inserted into the sheet, but the data is all the same as the first file.
Is there a way to flush / reset ..... something, so the next read file data actually is the next file?
Excel VBA code snippet:
Public Const sRawFilePath As String = "\\server1\Sample.RAW.Files\"
----------------
Sub ImportCSV()
Dim sFullFilePath, sFile As String
fFIle = FreeFile()
sFile = Dir(sRawFilePath & "*.csv")
sFullFilePath = sRawFilePath & sFile
While sFile <> ""
Open sFullFilePath For Input As fFIle
While Not EOF(fFIle)
Line Input #fFIle, sLine
""
"take the sLine string and separate the comma delimited values for insertion into columns "
"This part works fine"
""
Wend
Close fFIle
sFile = Dir()
Wend
End Sub
Stepping through the code I can confirm the next file is in the queue, but the read data is not representing the next file, just the first file, ... and always the first file even though 20 more files are read.
PS - This forum has been an amazing resource.
The problem is you define sFullFilePath which locks in the file that you're opening. So even though you're successfully looping through the files with Dir, you will only open the first one because you locked it in. Don't use that variable at all:
'Change this line
Open sFullFilePath For Input As fFIle
'To be this instead
Open sRawFilePath & sFile For Input As fFIle
Rather than executing Dir(sRawFilePath & "*.csv") in every call, you should just execute Dir in subsequent calls. The error causes you to re-read the first file again and again.
The title is messy, my apologies. Not sure the best way to word that, so if you a better suggestion, please.
The script I have works, but I'm having trouble keeping the leading zeros. I have tried to insert the .NumberFormat = "#", but I can only do that after I have created the file. I also tried adding the "'" at the leading zero when it puts the text into the file and it does add it, but doesn't apply it. It just keeps the "'" in front of the zero.
Suggestions? Thank you in advance!
Original number: 00099999 ----
Currently adds to file as: 99999 ----
If I add "'", it adds to file as: '00099999
Here's the snippet:
FName = i & "_INPUT" & ".csv"
If FName = False Then
Exit Sub 'user cancelled
End If
FNum = FreeFile
Open FName For Output Access Write As #FNum
For Each ir In range
If ir > 0 Then
strtest = ir
newnum = ExtractNumber(strtest)
End If
S = newnum & Chr(9) 'build each line
S = Left(S, Len(S) - 1) 'remove trailing tab
Print #FNum, S 'print to file
Next ir
Close #FNum
End If
How are you testing the CSV file? If you reopen it in Excel, it will remove the leading zeroes at that point - if you open it in Notepad they should still be there, assuming they were written to the file originally.