I am trying to use the Spreadsheet::ParseExcel::SaveParser plugin using example code at both metacpan.org and on SO and I cannot define the template (workbook).
I have played around with variations on the new statement, quotes, file parh, etc - nothing works. I put a die after the template statement and it prints the error message. Without that I have either a $template->worksheet() or worksheets() statement and if I skip the die I get a different message. I confirmed that the path to the Excel file is correct. I also new()'ed Spreadsheet::ParseXLSX instead and the code got past the template undefined problem - of course it crashed when I tried to do an AddCell.
use Spreadsheet::ParseExcel;
use Spreadsheet::ParseExcel::SaveParser;
my $saveParser = Spreadsheet::ParseExcel::SaveParser->new();
my $template = $saveParser->Parse("some Excel file verified to exist");
die "Error! Template not defined!\n" if (!defined($template));
dies
use Spreadsheet::ParseExcel;
use Spreadsheet::ParseExcel::SaveParser;
my $saveParser = Spreadsheet::ParseExcel::SaveParser->new();
my $template = $saveParser->Parse("some Excel file verified to exist");
my $worksheet = $template->worksheet(0);
Can't call method "worksheet" on an undefined value at ../bin/update_tp.pl line nnn. It also errors out if I use the worksheet name instead of number.
Obviously I expect the $saveParser->Parse command to return a valid object so I can work with it - it doesn't. FYI all modules I'm using are at the current rev of 0.65 except WriteExcel (which isn't relevant yet), which is 2.4.
Think you'd want to track down what error-handling is available for the Parse() function by reading the CPAN page for this module. Find and adapt that error-handling to give you an inkling of why Parse() would be failing. Your error about "worksheet on an undefined value" is indicative of that call failing. Could be you're not escaping file paths, maybe you don't have read permissions on the file, lots of other reasons Parse() could be failing. Eww, just went and looked myself, and there's fairly inadequate error-handling documented for that function. Maybe try die'ing with some error-handling variables? See https://perldoc.perl.org/perlvar.html#Error-Variables
Related
I'm trying to run a piece of code in vba but I'm still getting this error whenever I try to run it.
When I use debug the cursor on top of the 2nd line says "partDocument1 = Nothing"
Here's the code:
Set partDocument1 = documents1.item(Right(activeComponentWorksheet.cells(R, tem).Value, nameLength))
Set part1 = partDocument1.Part
Set body1 = part1.Bodies.item("PartBody")
selection1.Add body1
I'm just trying to create a part from the excel values by using macros. Could anyone explain why would this error happen?
This error message "Run time error method failed" is a general error message that can occur for a variety of reasons in VBA. It typically indicates that an operation that the code is trying to perform has failed, but without more information about the error and the specific line of code that is causing the issue, it is difficult to determine the exact cause of the problem.
One possible cause of this error in the provided code snippet is that the documents1.item(Right(activeComponentWorksheet.cells(R, tem).Value, nameLength)) method call is returning Nothing. This means that the item being passed as the argument to the method is not found in the documents1 collection. This will cause the subsequent Set part1 = partDocument1.Part and Set body1 = part1.Bodies.item("PartBody") line of code to throw the "Run time error method failed" error.
You can try to debug the error by adding some debug information and check if the variable partDocument1 is not equal to nothing before the error is thrown.
If partDocument1 Is Nothing Then
Debug.Print "partDocument1 is not found"
End If
You can also try to check if the value of the Right(activeComponentWorksheet.cells(R, tem).Value, nameLength) is matching with the value that you are expecting.
It's also possible that the problem is related to the activeComponentWorksheet.cells(R, tem).Value cell value or with the nameLength variable, it may be referencing a non-existent cell or it may contain a value that is not expected.
It's also possible that the problem is with the Bodies.item("PartBody") method, it may be that the body is not present or the name passed to the method is not correct.
These are some possible causes of the problem, but without more information about the specific environment and configuration of the code, it is difficult to provide a more specific solution.
Using VBA, I tried to use the NI-488.2 calls directly, instead of using VISA COM. However, when I try to use NI-488.2 commands in VBA, I get the following error message :
''Sub or Function not defined''.
That is, when calling Call SendIFC(BOARD_ID) or Call EnableRemote(BOARD_ID, intAddrList()), Call SendGPIB(osa, ":mmem:stor:grap color,bmp,""test"",int"), = RecieveBinaryGPIB(osa, byteData()), etc...
My first guess would be that I am simply missing the correct library. (Or is there any deeper issue here?). For now, I added the VISA COM 3.0 Type Library and the VISA COM 488.2 Formatted I/O 1.0 to the Excel references.
Here is a sample code from YOKOGAWA (slightly edited) that can be found online and applies to Visual Basics, but that I could not run in VBA. I removed most of the code for clarity purpose. It simply saves a screenshot in internal memory.
Private Sub SaveImage()
Const BOARD_ID = 0 'GP-IB Interface card Address
Const osa = 1 'OSA GP-IB Address
Dim intAddrList(31) As Integer
'----- GP-IB Interface setting
' send IFC
Call SendIFC(BOARD_ID)
' assert th REN GPIB line
intAddrList(0) = NOADDR
Call EnableRemote(BOARD_ID, intAddrList())
' GPIB time out setting
Call ibtmo(BOARD_ID, T30s) 'Time out = 30sec
'----- send command to OSA
Call SendGPIB(osa, "CFORM1") ' Command mode set(AQ637X mode)
Call SendGPIB(osa, ":mmem:stor:grap color,bmp,""test"",int")
'----- Disconnect
Call EnableLocal(BOARD_ID, intAddrList())
End Sub
Now we have the code... you have now edited out the useful bits... I'm going to backtrack a bit and say that even if you get direct calls to work you’re still going to have a problem extracting the files.
I’m going to guess you’re getting "Undefined header" errors if you query the OSA with "SYST:ERR:ALL?" and this is quite possibly because the query command for the data is invalid.
I’ve notice you’re using including the data type your command:
":mmem:data? ""test.bmp"",int"
"test.bmp",int,0 is what you might see if you query the directory, however, it is not needed when extracting the file.
try using:
":mmem:data? ""test.bmp"""
(The number of quotations are to include them in the string)
If not, what is the GPIB error?
At this point, I believe it may be a file I/O issue.
While utilizing a Powershell script invoking Excel methods to go through a .csv file from a website, powershell is attempting to cast placeholders for data that is too long for a cell "#######" instead of the date and time contained within the 'cell' (search engines may need 'pound sign' or 'hashtag' to reach this result).
Below is the offending portion of the script.
[DateTime]$S = $sheet.Cells.Item($rowS+$i,$colS).text
[DateTime]$G = $sheet.Cells.Item($rowG+$i,$colG).text
[DateTime]$A = $sheet.Cells.Item($rowA+$i,$colSWScan).text
The data should exist as MM/DD/YYYY HH:MM, but is being read by Powershell/PSExcelModule as #######, which is what is displayed with the Excel GUI when opening the file.
This is only a portion of what the entire script does. Any suggestions on how to resolve the error while maintaining usage of PSExcel-Module would be most helpful.
Stackoverflow seems to have an issue with me posting the verbose error message, and this is my first post. Let me know if that would be helfpul with troubleshooting.
Edit for comment #1:
# Create an instance of Excel.Application and Open Excel file
$objExcel = New-Object -ComObject Excel.Application
# Open the file
$workbook = $objExcel.Workbooks.Open($file)
# Activate the first worksheet
$sheet = $workbook.Worksheets.Item($sheetName)
$objExcel.Visible=$false
After getting my head out of 'Excelland', I realized it may be easier to re-write the script to utilize the .csv organization (the original imported file for the script was a .xlsx), but I am admittedly unfamiliar with .csv scripting. However, the original question still stands while I re-write the code as I may need to switch back to .xlsx imported documents. Thank you for the suggestion J E Carter II.
Answer:
$objExcel.Cells.EntireColumn.AutoFit()
Credit to J E Carter II
When you open an excel file as an object under windows, you're launching excel.
You might be able to add the following commands to your excel object handle to get the data to represent correctly.
$objExcel.Cells.Select
$objExcel.Cells.EntireColumn.AutoFit
Do this before getting values from cells. If that doesn't work, let me know and I can find some csv handling examples.
Those might work better on the $workbook object. I can't remember which is implicit when recording a macro (which is how I got those).
It's also possible you may need to precede those two lines with something like
$workbook.Sheets("sheetname").Select
I'm trying to read multiple csv files, in a loop, and then perform some analysis on all o them.
I'm using MatlabR2015b and Excel 2016.
the problem is that at the second call to xlsread I get the following error:
>>xlsread('R:\Experiments\ResoFreq_vis_BEH\TapFlick_vis_BEH\Data\s01_rr\1_fingerTapping_s01_rr.csv')
Error using xlsread (line 251)
No explanation no message, nothing.
after some debugging I've found it fails at the following command:
Excel.workbooks.Open(filename, 0, readOnly);
in the openExcelWorkbook.m file which is somewhere down the stack of xlsread.
I found very few people with the same problem and their solution was to force the EXCEL32 process to close using the following code:
[~, computer] = system('hostname');
[~, user] = system('whoami');
[~, alltask] = system(['tasklist /S ', computer, ' /U ', user]);
excelPID = regexp(alltask, 'EXCEL.EXE\s*(\d+)\s', 'tokens')
for i = 1 : length(excelPID)
killPID = cell2mat(excelPID{i});
system(['taskkill /f /pid ', killPID]);
end
However, this does not work for me.
after somemore digging I tried to manually look at the csv im trying to open, while debugging, meaning after stopping at the breakpoint at the Excel.workbooks.Open call, I used:
actxserver('Excel.Application')
ans.Workbooks.Open(filename)
which gave me the following error:
Error using Interface.000208DB_0000_0000_C000_000000000046/Open
Which is associated to Workbooks when looking at the excel process through the matlab inspector.
That is all the information I've managed to find related to my problem.
the only thing that works for me at the moment is running xlsread, then manually closing the excel process from the task manager, then running it again, until I have all my data, and then analyze, which is not a possible considering the amount of files I need to load.
I cannot use csvread as my files have mixed types, and every other function i've tried does not read the csvs properly
(I have a field which looks like this "[,...,]" and that field keeps getting interpreted as multiple rows in every function except with xlsread)
and thus I feel like I have no option but to fix xlsread somehow.
I would gladly provide anymore information that is necessary to solve this
thanks.
you should use csvread instead of xlsread, becuase xlsread just read .xls and .xlsx files.
This is similar to A copy of Excel Addin is created in My Documents after saving, except that I'm working with Perl instead of VBA, and xls files instead of xlsm, and the negative impact of the behavior is different.
I've inherited a Perl script (Perl 5.8.8) that is running on Windows 2003 Server as SYSTEM. After copying an Excel 2003 template file to a unique, fully defined path location, it opens the unique file in Excel using OLE, edits the file, saves the file, and closes the file. What results is the edited file being saved both in the correct, fully-defined path location, and also in the Default User profile's Documents folder.
This causes thousands of these files to accumulate on the C: drive, as every new admin to be hired gets a copy in his Documents folder.
Adding the code that sets the value of $OUT:
if (!$db->Sql("EXEC GetDetails 'name'"))
{
while ($db->FetchRow()>0)
{
#DataIn = $db->Data();
$name = $DataIn[0];
$IN = $DataIn[1];
$OUT = $DataIn[2];
opendir(DIR,"$OUT") || die "$OUT directory does not exist $!\n";
#... loop of proprietary code
#...
#Completed = $db1->Data();
#...
&formatExcelReport #The code that I previously posted
#...
# more proprietary code
# end of loop
} #end of while
}#end of if
The code I originally posted:
# Initialize Excel object
eval {Win32::OLE->new('Excel.Application', 'Quit')};
eval {$Excel = Win32::OLE->GetActiveObject('Excel.Application')};
unless (defined $Excel)
{
$Excel = Win32::OLE->GetActiveObject('Excel.Application')
|| Win32::OLE->new('Excel.Application', 'Quit');
}
$infiles = "Report_Template.xls";
$infiles = $OUT."/".$infiles;
$db6->Sql("EXEC FormatResults '".$Completed[0]."','".$Completed[1]."'");
$row = 2;
$fileName = $Completed[0]."_".$Completed[1];
$uniquefile = $fileName.$printdate.".xls";
# $OUT is a fully defined path on the E: drive
$reportfile = "$OUT"."\\".$uniquefile;
copy($infiles,$reportfile);
$Book = $Excel->Workbooks->Open("$reportfile");
$sheetnum = 1;
my $Sheet = $Book->Worksheets($sheetnum);
# Set Headers
$Header = $Sheet->PageSetup->{'CenterHeader'};
$Header = $Header." Results Test Code: ".$Completed[0]." Worksheet: ".$Completed[1]." Date: ".$headerdate;
$Sheet->PageSetup->{'CenterHeader'}= $Header;
# More file editing
# ...
$Book->Save();
$Book->Close(0);
Win32::OLE->new('Excel.Application', 'Quit');
Is the root of this problem the Save() command? Should I be using SaveAs() instead?
Any other feedback about how Excel is being used welcome, as well.
Thanks!
I don't see what causes this behavior, but here are a few things to try.
The template and the file it is copied to have names
$infiles = $OUT."/".$infiles;
$reportfile = "$OUT"."\\".$uniquefile;
Use the same separator.
Try to suppress some possible setting dictating that another copy be made. Perhaphs
$Excel->Application->{CreateBackup} = 0;
However, this may not be the correct property -- search the VB or Excel documentation for properties that may result in Excel saving an extra copy. (It needn't be "backup".)
Try to create a new file and use SaveAs, as a test to see whether you get two files again. The template copying may be setting it off to Save an extra copy (even though I don't see how). I'd say it's either that, or some general setting that need be turned off.
The rest is the original post, about using SaveAs, whereby I thought that a new file is created
You would use SaveAs to write a new file. See saveas in MSDN library
Saves changes to the workbook in a different file.
Using the save method may result in saving two files fro some reason, as noted in the answer by Borodin. This page also advises to use SaveAs for a new file
The first time you save a workbook, use the SaveAs method to specify a name for the file.
Once you change to using SaveAs there should be a confirmation dialog to deal with. If you want to suppress that you can set a property, with one (or either?) of
$Excel->Application->{DisplayAlerts} = 0;
# or
$Excel->{DisplayAlerts} = 0;
For a number of options, including backups for example, see the Chapter on OLE automation in PERL in a Nutshell.
A note on some other resources. There is a cookbook of sorts in this post on perlmonks. A listing of various operations is given in this SO post.
Finally, I don't know how deep the reasons for using OLE are but if it is only about writing some Excel files there are other modules. For example the very well regarded Spreadsheet::WriteExcel and Excel-Writer-XLSX.
That's very strange Perl code. eval without checking $# afterwards is just wrong -- you need to know if a step of your code has failed for the following steps to make sense
It looks like the problem is in your call to copy($infiles, $reportfile). That will save one copy of the file, while $Book->Save and $Book->Close will save another