Unable to save Excel file after modification using Ruby & win32ole - ruby

Using http://ruby-doc.org/stdlib/libdoc/win32ole/rdoc/classes/WIN32OLE.html as a guide I have written the following:
require 'win32ole'
excel = WIN32OLE.new('Excel.Application')
excel.visible = false #Setting this is 'true' doesn't reveal anything
workbook = excel.workbooks.open('C:\myspreadsheet.xlsx')
worksheet = workbook.worksheets('sheet1')
worksheet.Activate
data = worksheet.UsedRange.Value
p data.size #This works! - My spreadsheet has 3987 rows.
p data[3932] #This works, too! - I can "see" row 3932.
worksheet.Rows(3932).Insert #Insert a row above row 3932
data = worksheet.UsedRange.Value
p data.size #Returns 3988! This would seem to indicate that I've successfully added a row since it was just 3987.
workbook.saved = true #Save the workbook and quit.
excel.ActiveWorkbook.Close(0)
excel.Quit()
When I open the Excel spreadsheet after all of this it is unchanged. Any ideas?

Setting the Saved property of a Workbook object to True does not cause the workbook to be saved. That property is used as a flag to show whether a workbook has unsaved changes. Setting it to True is a simple way of preventing the "Do you wish to save..." dialog appearing when Excel is closed.
To actually save the workbook, you need the Save method of the Workbook object. This method doesn't return anything so I would assume that workbook.Save would do the trick (I have no experience of Ruby, unfortunately, so can't be 100% sure on that)

Related

How do I hide columns using rubyXL 3.4.0 or later?

How do I hide columns using rubyXL 3.4.0 or later?
The example here (https://github.com/weshatheleopard/rubyXL/issues/145) appears to be out-of-date. (sheet.cols.find now returns an Enumerator, so doesn't have a hidden method.)
Code from rubyXL issue #145:
# Assuming that the cells/rows/cols are respectively locked in the test file:
doc = RubyXL::Parser.parse('test.xlsx')
sheet = doc.worksheets[0]
sheet.sheet_data.rows[0].hidden
=> nil
sheet.sheet_data.rows[1].hidden
=> true
(c = sheet.cols.find(0)) && c.hidden
=> nil
(c = sheet.cols.find(1)) && c.hidden
=> true
xf = doc.workbook.cell_xfs[c.style_index || 0]
xf.apply_protection && xf.protection.locked
=> true
xf.apply_protection && xf.protection.hidden
=> true
I figured it out:
The following code does generate a new workbook with column B hidden:
require "rubyXL"
require "rubyXL/convenience_methods"
workbook = RubyXL::Workbook.new
sheet = workbook.worksheets.first
sheet.add_cell(0,0, "Sam")
sheet.add_cell(0,1, "George")
sheet.add_cell(0,2, "John")
sheet.cols.get_range(1).hidden = true
workbook.write('hide_b.xlsx')
(I also put a copy of this code here: https://github.com/kurmasz/rubyXL-recipes)
the example you offer is not to hide columns but to get the hidden
status of columns
Edited to prevent misleading others
looks like rubyXL doesn't have feature to hide columns its
main purpose is to parse xlsx file the hidden attribute is only for
reading, you can't change it with rubyXL
actually you can, see the solution Zack figure out
I found this gem, write_xlsx to have capability to hide columns /
rows but in contrast, it's for creating xlsx they have
example in the github repo about how to hide I didn't find any
other gem that can achive this goal easily(hide specific columns from
an existed xlsx file) maybe you can
read the original xlsx file with rubyXL
use the data parsed from rubyXL and make a whole new xlsx file with write_xlsx gem (hide the target column in this step)
replace original xlsx file

Access 2013: Send the form's current record only to a PDF using a report

I have a form where users input all of their data. There is a 'Save' button which saves the record, and leaves the form up and active.
Before I close the form, I need to take that newly saved record and output the associated report to a PDF file.
My problem right now is that the output to the PFD is sending all records in the table, not just the record in the form.
Here is my code at this point.
Private Sub cmdSave_Click()
Dim outl As Outlook.Application
Dim mi As Outlook.MailItem
Dim strWhere As String
Cause = "SaveButton"
DoCmd.RunCommand acCmdSaveRecord
'Save the Record
Me.btnClose.SetFocus
If Me.DateOfVisit <> "" Then
Me.RepStatus = "Report Saved!"
Me.btnNewReport.Visible = True
'Now, print the report to a PDF File
DoCmd.OutputTo acOutputReport, "rptReports", acFormatPDF,"C:\ReportTest.pdf", False
End If
End Sub
As a side note, it is required that the users would not see a report pop up on the screen and then quickly disappear.
Thanks for any assistance.
Looks like I finally noodled it out.
I added the following lines and now it is working.
Turns out that the OutputTo has no way to pass in any search criteria.
So, I opened the report in Hidden mode so the users don't see anything and then use the OutputTo to send it to a PDF.
'Now, print the report to a PDF File
DoCmd.OpenReport "rptReports", acViewReport, , "[ReportID] = " & [ReportID], acHidden
DoCmd.OutputTo acOutputReport, "rptReports", acFormatPDF, "C:\TG QUOTE SYSTEM\Meeting Reports\ReportTest.pdf", False
DoCmd.Close acReport, "rptReports"
End If
Thanks all.

how to send contents of a textbox in vb6 to a notepad document

I am trying to send the data inserted into a textbox into a notepad document so that the data can be held for future reference, as i am trying to create an assessment date reminder as i am a student.
But whenever i try to send the data with this code by writing data = "txtAssign_Name, txtAssign_Due" when i check the notepad after running the program, all that is in the document is txtAssign_Name, txtAssign_Due.
Private Sub Form_Load()
Dim Data As String
txtAssign_Name.Text = ""
txtAssign_Due.Text = ""
Data = ""
Open "F:\Personal\date calender test - Copy\test.txt" For Output As #1
Print #1, Data
Close #1
End Sub
Try this:
Data = txtAssign_Name.Text & ", " & txtAssign_Due.Text
(In the lines above, you will want to NOT set those values to "")
Note - using the built in VB6 writing to text files will result in your output being formated in a way so that VB6 can read it back in again. So all strings will have quotes aroud them, other values are displayed in a variety of odd ways, commas seperate all values.
If the output text file is desired to be primarily for human use, then I find using the richtextbox control a better way of creating the file. Add it from Project -> Components -> Controls -> Microsoft Rich Textbox Control 6.0
Add the Rich text box to your form (you can set visible = false if you don't want users to see it). Add your data to it something like this:
RichTextBox1.text = txtAssingn_Name.text & ", " & txt_Assing_Due.text
' If you need to add more things, add them on to the end like this
RichTextBox1.text = richtextbox1.text & vbcrlf & "More text on the next line"
Then, when all the data is added, you just do this
RichTextBox1.SaveFile "C:\Test.txt", rtfText
rtfText is a visual basic constant, that tells the RTB to save as plain text. The alterntaive is rtfRTF. You can learn more about the RTB on MSDN
OK, so a comment above states that you want to be able to read the data back into VB.
The code as it shown in the question will just output a blank text file, as the variable Data is set to "", so that is all that will be output.
What you need is something like this
private Sub SaveData()
dim SaveFile as integer
SaveFile = Freefile ' This gets a file number not currently in use
Open "F:\Personal\date calender test - Copy\test.txt" For Output As #Savefile
write #SaveFile, txtAssign_Name.Text, txtAssign_Due.Text
close #savefile
end sub
And call SaveData in the appropriate place. NOT form load, as the user won't have entered anything at this point. Either after the user has pressed a button, or on Form_Unload if you want it to autosave on form close.
To populate your form again, something like this
private sub LoadData()
dim LoadFile as integer
dim StringData as string
loadfile = freefile
Open "F:\Personal\date calender test - Copy\test.txt" For Input As #loadfile
input #loadfile, StringData
txtAssign_Name.Text = StringData
input #loadfile, StringData
txtAssign_Name.Text = stringdata
close #loadfile
end sub
You should also add error handing whenever working with files. VB6 is quite particular and its very easy to throw an exception when dealing with files.

Using Loop Conditions in Excel-Ruby Watir Scripts

I'm New to Ruby-Watir ..And am Checking Login Functionality for one Application that Multiple values like (Invalid user& Password ,Valid Username & Password)coming from Excel Sheet.
reqire'watir-webdriver'
require 'win32ole'
require 'roo'
b = Watir::Browser.new
b.goto 'http://tech/mellingcarsweb/Admin/Login.aspx'
xl = WIN32OLE.new('excel.application')
wrkbook= xl.Workbooks.Open("C:\\Excel\\cars.xlsx")
wrksheet= wrkbook.Worksheets(1)
wrksheet.select
$username= wrksheet.Range("A1").Value
$password= wrksheet.Range("B1").Value
b.text_field(:id, "MainContent_txtUsername").set($username)
b.text_field(:id, "MainContent_txtPassword").set($password)
b.button(:id, "MainContent_btnLogin").click
b.alert.ok
$username1= wrksheet.Range("A2").Value
$password1= wrksheet.Range("B2").Value
b.text_field(:id, "MainContent_txtUsername").set($username1)
b.text_field(:id, "MainContent_txtPassword").set($password1)
b.button(:id, "MainContent_btnLogin").click
puts "Authorised Entry"
This code is working fine.What my need is.. using loop statements i need to execute for multiple times.
I don't Know how to use looping conditions in Excel.And i have seen lot of Examples But none of them are clear.Sorry am not able to understand.Will anyone Explain me in proper way of using looping Conditions in Excel ruby.
Thanks
Given that you are testing valid and invalid logins, I am not sure that it makes the most sense to write a loop. The problem with a loop is that, each iteration needs to know what the expected result is. You would likely need to include that information in your spreadsheet. You might be better off creating specific individual tests for each valid and invalid scenario (ie one assertion per test).
To answer your question, you can convert the excel range to a 2D array and then iterate through each row of data. To get the 2D array:
require 'win32ole'
#Open the spreadsheet
xl = WIN32OLE.new('excel.application')
wrkbook= xl.Workbooks.Open('C:\Users\Someone\Desktop\Logins.xlsx')
wrksheet= wrkbook.Worksheets(1)
#Convert the range of cells to a 2D array
login_data = wrksheet.range("A1:B2").value
#Output of the 2D array
p login_data
#=> [["jsmith", "password1"], ["jdoe", "password2"]]
Each element of the 2D array is a row of the excel data. You can iterate through it using the each method.
#Start your browser
b = Watir::Browser.new
#Loop through the login data
login_data.each do |data|
#Determine the user id and password for the row of data
user = data[0]
password = data[1]
#Go to the login page
b.goto 'http://tech/mellingcarsweb/Admin/Login.aspx'
#Input the fields and submit
b.text_field(:id, "MainContent_txtUsername").set(user)
b.text_field(:id, "MainContent_txtPassword").set(password)
b.button(:id, "MainContent_btnLogin").click
#Do something to validate the result
end
Google for ruby loops. This looks like a good introduction: http://www.tutorialspoint.com/ruby/ruby_loops.htm

Export data from listview to OpenOffice VB6

I have a program that displays data from a CSV file into a ListView.
I then have a button called "Reports" - when I click this I want the data to be displayed from the ListView/CSV file in OpenOffice Calc.
This is my code:
Private Sub cmdReports_Click()
Dim oSM As Object
Dim oDesk As Object
Dim oDoc As Object
Dim oSheet As Object
Dim i As Integer
'Instanciate OOo : this line is mandatory with VB for OOo API
Set oSM = CreateObject("com.sun.star.ServiceManage…
'Create the first and most important service
Set oDesk = oSM.CreateInstance("com.sun.star.frame.D…
'Create a new doc
Set oDoc = oDesk.loadComponentFromURL("private:fact… "_blank", _
0, arg())
'Get the first sheet in the doc
Set oSheet = oDoc.getSheets().getByIndex(0)
With oSheet
For i = 1 To ListView1.ListItems.Count
.cells(i, 1) = ListView1.ListItems(i).Text
.cells(i, 2) = ListView1.ListItems(i).SubItems(1)
.cells(i, 3) = ListView1.ListItems(i).SubItems(2)
.cells(i, 4) = ListView1.ListItems(i).SubItems(3)
Next
End With
End Sub
At the moment all my button is doing giving me Run-time error '438' Object does not support this property or method
When I debug this line is highlighted:
.cells(i, 1) = ListView1.ListItems(i).Text
This code was written for Excel but I edited it so it can be displayed in OpenOffice Calc.
Can anyone help please?
Thanks
It means exactly what it says - the statement is using a property of method that isn't supported by the Ole Automation interface. First question: can you use a type library (see the References dialogue - is there something like OpenOffice Calc in the list)? Knowing what methods and properties are available at compile time is much better - you can do the same with Microsoft Excel. Then you could declare your variables as a specific type, rather than "As Object".
Not knowing OpenOffice, I looked for documentation on OpenOffice, and found the next best thing, Star Office. Try: http://www.openoffice.org/api/basic/man/tutorial/tutorial.pdf . Look at page 64, section 4.4 for documentation on the spreadsheets. The object model looks different to Office, which would explain your problem.
It looks as if you need to use the Sheet.getCellByPosition() method, rather than the Cells() method, e.g.
GetCell = oSheet.getCellByPosition (nColumn , nRow)

Resources