Copy range of cells from Excel - excel

I'm trying to copy some cells from Microsoft Excel to another program using AutoIt, but I can just copy one cell at a time. Is there a way to copy a group or range of cells?
My code:
Local $Resultcpf = Excel_RangeRead($oWorkbook, default, "L4")
ClipPut($Resultcpf)
$Data = ClipGet()

"Is there a another way to copy a group of range?"
As per Documentation - User Defined Function Reference - _Excel_RangeRead() :
Reads the value, formula or displayed text from a cell or range of cells of the specified workbook and worksheet
Example :
#include <MsgBoxConstants.au3>
#include <Array.au3>
#include <Excel.au3>
Global Const $g_sFileDoc = 'C:\document.xlsx', _
$g_sRange = 'L:L', _; 'L1:L4'
$g_sPrompt = 'Press [CTRL] + [V] to paste contents of %s.'
Global $g_oExcel = _Excel_Open(), _
$g_oBook = _Excel_BookOpen($g_oExcel, $g_sFileDoc)
Global $g_aData = _Excel_RangeRead($g_oBook, Default, $g_oBook.ActiveSheet.Usedrange.Columns($g_sRange))
Global $g_sData = _ArrayToString($g_aData)
_ArrayDisplay($g_aData)
ClipPut($g_sData)
MsgBox($MB_SYSTEMMODAL, #ScriptName, StringFormat($g_sPrompt, $g_sRange))

You have to define the range by B3:C5 for two columns or A1:A17 for one column and so on. The range has to be divided by colon ":" sign.
#include-once
#include <Array.au3>
#include <Excel.au3>
Global $sFileExcel = #DesktopDir & '\MyExcelSheet.xlsx'
Global $sExcelRange = 'B3:C5'
Func _readExcelContent()
Local $oExcel = _Excel_Open()
Local $oWorkbook = _Excel_BookOpen($oExcel, $sFileExcel)
Local $aData = _Excel_RangeRead($oWorkbook, Default, $sExcelRange, 2)
_Excel_Close($oExcel, Default, True) ; excel will be closed
Return $aData
EndFunc
Global $aData = _readExcelContent()
_ArrayDisplay($aData) ; this is just a preview of the read data
ClipPut(_ArrayToString($aData))
The result/output could be :
text1|
text2|text4
text3|
Depending on Excel content of course.

Related

How to use Autofill/Filldown with a range of values

I have been trying to get Excel to apply a formula over a set of columns and then extend the pattern across the entire set of rows.
This has led to the following code:
For i = 0 To avgsheetNames.Count - 1
If Contains(CStr(avgsheetNames(i)), "Scores") = True Then
With mainWorkBook.Worksheets(avgsheetNames(i))
strFormulas(1) = "=SUM(Aggregated_Internal_Scores!I2:I7)/6"
strFormulas(2) = "=SUM(Aggregated_Internal_Scores!J2:J7)/6"
strFormulas(3) = "=SUM(Aggregated_Internal_Scores!K2:K7)/6"
strFormulas(4) = "=SUM(Aggregated_Internal_Scores!L2:L7)/6"
strFormulas(5) = "=SUM(Aggregated_Internal_Scores!M2:M7)/6"
strFormulas(6) = "=SUM(Aggregated_Internal_Scores!N2:N7)/6"
strFormulas2(1) = "=SUM(Aggregated_Internal_Scores!I8:I13)/6"
strFormulas2(2) = "=SUM(Aggregated_Internal_Scores!J8:J13)/6"
strFormulas2(3) = "=SUM(Aggregated_Internal_Scores!K8:K13)/6"
strFormulas2(4) = "=SUM(Aggregated_Internal_Scores!L8:L13)/6"
strFormulas2(5) = "=SUM(Aggregated_Internal_Scores!M8:M13)/6"
strFormulas2(6) = "=SUM(Aggregated_Internal_Scores!N8:N13)/6"
mainWorkBook.Worksheets(avgsheetNames(i)).Range("C2:H2").Formula = strFormulas
mainWorkBook.Worksheets(avgsheetNames(i)).Range("C3:H3").Formula = strFormulas2
mainWorkBook.Worksheets(avgsheetNames(i)).Range("C2:H3").AutoFill Destination:=mainWorkBook.Worksheets(avgsheetNames(i)).Range("C2:H32")
End With
End If
As you can see I have tried to provide the pattern I am going for where the values extracted from the "Aggregated_Internal_Scores" sheet should follow the pattern I2:I7 > I8:I13 > I14:I19 and so on.
However, when the macro has been executed what I get is I2:I7 > I8:I13 > I4:I9 > I10:I15?
It seems Excel is taking the block C2:H3 as the pattern and just incrementing by 2 at the start of every block.
Can you anyone explain where I have gone wrong and how I can specify that I want the extraction of sheet values to follow a certain pattern?
Thank you in advance!
Use:
mainWorkBook.Worksheets(avgsheetNames(i)).Range("C2:H32").Formula = "=SUM(INDEX(Aggregated_Internal_Scores!I:I,(ROW($ZZ1)-1)*6+2):INDEX(Aggregated_Internal_Scores!I:I,(ROW($ZZ1)-1)*6+7))/6"
Replace everything inside the If with that.
If one has Office 365 with dynamic array formula then use:
mainWorkBook.Worksheets(avgsheetNames(i)).Range("C2:H32").Formula2 = "=SUM(INDEX(Aggregated_Internal_Scores!I:I,SEQUENCE(6,,(ROW($ZZ1)-1)*6+2))/6"

Python3 - Openpyxl - For loop to search through Column - Gather information Based on position of first cell location

UPDATE!
My goal is to modify an existing Workbook ( example - master_v2.xlsm ) and produce a new workbook (Newclient4) based on the updates made to master_v2.
I'm using a single sheet within master_v2 to collect all the data which will be determining what the new workbook will be.
Currently using multiple if statements to find the value of the cells in this "repository" sheet. Based on specific cells, I'm creating and adding values to copies of an existing sheet called "PANDAS".
My goal right now is to create a dict based on two columns. The loop through
the keys so that every time I get a hit on a cell, I will gather values from specific keys.
That's listed below:
from openpyxl import load_workbook
# Start by opening the spreadsheet and selecting the main sheet
workbook = load_workbook(filename="master_v2.xlsm",read_only=False, keep_vba=True)
DATASOURCE = workbook['repository']
DATASOURCE["A:H"]
cell100 = DATASOURCE["F6"].value
CREATION = cell100
cell101 = DATASOURCE["F135"].value
CREATION2 = cell101
cell107 = DATASOURCE["F780"].value
CREATION7 = cell107
if CREATION.isnumeric():
source = workbook['PANDAS']
target = workbook.copy_worksheet(source)
ss_sheet = target
ss_sheet.title = DATASOURCE['H4'].value[0:12]+' PANDAS'
if CREATION2.isnumeric():
source = workbook['PANDAS']
target = workbook.copy_worksheet(source)
ss_sheet = target
ss_sheet.title = DATASOURCE['H133'].value[0:12]+' PANDAS'
if CREATION3.isnumeric():
source = workbook['PANDAS']
target = workbook.copy_worksheet(source)
ss_sheet = target
ss_sheet.title = DATASOURCE['H262'].value[0:12]+' PANDAS'
else:
print ("no")
workbook.save(filename="NewClient4.xlsm")
Instead of the many if statements I was hoping to be able to loop through the column as explained above,
once I found my value, gather data and copy it over to a copy of sheet which is then filled out by other cells. Each time the loop comples, I want to do repeat on the next match of the string.. but I'm only this far and it's not quite working.
Anyone have a way to get this working?
( trying to replace the many one to one mappings and if statements )
for i in range(1,3000):
if DATASOURCE.cell(row=i,column=5).value == "Customer:":
source = workbook['Design details']
target = workbook.copy_worksheet(source)
ss_sheet = target
ss_sheet.title = DATASOURCE['H4'].value[0:12]+' Design details'
else:
print ("no")
Thank you guys in advanced

Save an already opened new Excel workbook using autoit

A windows application exports data into a new excel workbook.
I need to save that generated workbook using AutoIt.
I tried the below code.But it is not working.
Local $oExcel = ObjGet("","Excel.Application")
For $oWb in $oExcel.Workbooks
$oWb.Activate()
_Excel_BookSaveAs($oWb,"File name with full path",Default,True)
$oWb.Application.Quit
ExitLoop
Next
According to the documentation, you have to make sure your file extension and excel type match - i.e. Excel 2007 = xlsx
A valid path/file name, a valid type ( optional ) , overwrite = true.
Activate isn't necessary.
#include <excel.au3>
#include <ExcelConstants.au3>
Local $oExcel = ObjGet("","Excel.Application")
if NOT #error then
for $Workbook in $oExcel.Workbooks
; optional type $xlExcel7
; optional overwrite = true
_Excel_BookSaveAs($Workbook,"c:\drivers\keeper3.xlsx" )
next
_Excel_Close($oExcel,false,true)
EndIf
ConsoleWrite("END" & #CRLF)

Why is my "defined name" (range) value not being set with this Spreadsheet Light code?

I've got this code to apply a "header" (big, top-of-the-sheet "title") to a sheet:
// Initialize
private static SLDocument sl;
. . .
sl = new SLDocument();
// Create a Style
SLStyle styleHeading = sl.CreateStyle();
styleHeading.SetFont(FontSchemeValues.Major, 36);
styleHeading.Font.Italic = true;
styleHeading.Font.FontName = "Candara";
// Create a Defined Name (Range) and give it a value and style
sl.SetDefinedName("UnitName", "Sheet1!$A$1:$A$13");
sl.SetCellValue("UnitName", "Pennsylvania Platypi Presumptuously Parasailing");
sl.SetCellStyle("UnitName", styleHeading);
// Save the sheet
string appDataFolder = HttpContext.Current.Server.MapPath("~/App_Data/");
string spreadsheetLightFilename = "PlatypiTest.xlsx";
string fullspreadsheetLightPath = Path.Combine(appDataFolder, spreadsheetLightFilename);
sl.SaveAs(fullspreadsheetLightPath);
Note: I verified that "Sheet1" was right with this code:
var nameList = sl.GetSheetNames();
string s = nameList[0]; // "s" is "Sheet1"
The file is created and saved, but it is devoid of content; when I open it, cell A1 is highlighted, but is content-free.
Am I missing a vital step, or going about this completely wrong?
What are you doing is logically fine.
This line
sl.SetDefinedName("UnitName", "Sheet1!$A$1:$A$13");
indeed creates a named range. You can see it if you open the resulting file in Excel and look at the cell selector:
or the Name Manager:
The problem is though that Spreadsheet Light has a very basic support for Defined names - basically all you can do is to create a name and use it inside the formulas. All methods that manipulate content expect single cell reference. Btw, all these methods do not throw exception if you don't pass a valid cell reference, but return bool indicating success/failure.
For instance, if you change your code to
bool success1 = sl.SetCellValue("UnitName", "Pennsylvania Platypi Presumptuously Parasailing");
bool success2 = sl.SetCellStyle("UnitName", styleHeading);
you will see that both success variables are false.
Shortly, if you want to bring some content to the Excel file, you should do it cell by cell. It even does not support regular (unnamed) ranges.
Theoretically, at least, you could do it this way:
// from http://stackoverflow.com/questions/36481802/what-is-the-analogue-to-excel-interops-worksheet-usedrange-rows-in-spreadsheet
var stats = sl.GetWorksheetStatistics();
var rowcount = stats.NumberOfRows;
SLStyle entireSheetRangeStyle = sl.CreateStyle();
entireSheetRangeStyle.// (set style vals)
. . .
sl.SetRowStyle(1, rowcount, entireSheetRangeStyle);

Assign contents of Excel cell to string variable in AutoIT [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I am writing a script that I want to pull cell values from an Excel spreadsheet containing usernames and passwords. I wish to use two variables USERNAME and PASSWORD. I would like to use the data on each row and move down a row with each pass of the loop.
I have looked over Excel UDF included in AutoIT and ExcelCOM_UDF written by a third party. I cannot seem to find the answers I am looking for. This should be a very basic function of either of these, but I am having trouble.
I am not looking for a handout, so just a nice reference page is fine. BUT if you have a snippet of what I need, it will not hurt my feelings as I am not determined to write this code solely on my own.
My "A" column will contain the USERNAME variables, and the "B" column will contain my PASSWORD variables.
Added snippet of some code of what I have so far. I have not tried to pull anything from Excel yet, because I cannot find a command that seems to do what I am looking to do. Hopefully seeing the code will give a better picture of my goal.
I DO NOT WISH TO MODIFY THE SPREADSHEET PROGRAMMATICALLY, ONLY SET STRING VARIABLES FROM CELL TEXT.
...
$USERNAME = "usernameHere" ;I want to set this variable as the text from A1 of c:\test.xls
$PASSWORD = "passwordHere" ;I want to set this variable as the text from B1 of c:\test.xls
;Username Box
MouseClick("left",1179,488,1)
;Type username
Send($USERNAME)
;Password Box
MouseClick("left",1179,578,1)
;Type Password
Send($PASSWORD)
...
In order to read a spreadsheet containing a list of usernames and password. This function create an array with two dimensions. The first column contains usernames, the second the password. With this
#include <Array.au3>
#include <Excel.au3>
Func get_data_Excel($filePathExcel)
Local $error
Local $oExcel = _ExcelBookOpen($filePathExcel, 0)
$oExcel.Application.DisplayAlerts = False
$oExcel.Application.ScreenUpdating = False
$error = Int(#error)
Select
Case $error = 1
msgbox(16, "Erreur : Fermeture de l'application", "Code erreur _ExcelBookOpen : 1"&#CRLF&#CRLF&"Impossible de creer l'objet $oExcel avec _ExcelBookOpen")
Case $error = 2
msgbox(16, "Erreur : Fermeture de l'application", "Code erreur _ExcelBookOpen : 2"&#CRLF&#CRLF&"Impossible d'ouvrir le fichier "&$filePathExcel&" avec _ExcelBookOpen")
EndSelect
If $error > 0 Then
_ExcelBookClose($oExcel, 0) ; Close without save
Exit
EndIf
; Read column A (login) and column B (pwd)
_ExcelSheetActivate($oExcel, "sheet1")
$nb_columns = $oExcel.ActiveSheet.UsedRange.Columns.Count
$nb_rows = $oExcel.ActiveSheet.UsedRange.Rows.Count
Local $array_data_excel[$nb_rows][2]
Local $idx
For $idx = 0 To $nb_rows-1
$array_data_excel[$idx][0] = $oExcel.Activesheet.Cells($idx+1, 1).Value
$array_data_excel[$idx][1] = $oExcel.Activesheet.Cells($idx+1, 2).Value
Next
_ExcelBookClose($oExcel, 0)
_ArrayDisplay($array_data_excel, "Data from excel file")
EndFunc
And to use this function :
get_data_Excel("d:\users.xlsx")
#include <Excel.au3>
Local $MyUsernameArray[5] = [ "Hans", "Gerd", "Walter", "Klaus", "Peter" ] ;Your Username Array
Local $MyPasswordArray[5] = [ "12345", "I", "am", "so", "creative" ] ;Your Password Array
$oExcel = _ExcelBookNew(1) ;Set this to 0 if you want it to work in background
_ExcelWriteCell ( $oExcel, "Usernames", "A1" ) ;self explaining (i hope)
_ExcelWriteArray ( $oExcel, 2, 1, $MyUsernameArray ,1) ;^
_ExcelWriteCell ( $oExcel, "Passwords", "B1" );^
_ExcelWriteArray ( $oExcel, 2, 2, $MyPasswordArray ,1);^
_ExcelBookSaveAs($oExcel, #ScriptDir & "\PleaseAtleastPostSomeCodeNextTimeSoWeSeeYouTried", "xls") ;save the file
_ExcelBookClose($oExcel, 1, 0) ;exit and save
If you want to get all control with COM/Automation Excel, don't use the UDF , andd deep inside the Com/Automation with the function AutoIt ObjCreate. With this function you can get the control of the Object Excel in AutoIt
COM/Automation with Excel
1) Create reference on COM Object of target application (here this is Excel)
$oExcel = ObjCreate("Excel.Application")
2) Add some options on this instance
With $oExcel
.Visible = 1
.WorkBooks.Add
EndWith
3) And now the work can be begin (add some worksheet or data, save the workbook...)
With $oExcel
.ActiveWorkbook.Worksheets(1).Name = "SHEET_ONE"
.ActiveWorkbook.Worksheets(1).Cells(1,1) = "I believe i can fly !!!"
EndWith
Hacks 1 : Save As
; Create new file with one sheet named "SHEET_ONE"
Local $oExcel = ObjCreate("Excel.Application")
With $oExcel
.SheetsInNewWorkbook = 1
.Visible = 1
.WorkBooks.Add
.ActiveWorkbook.Worksheets(1).Name = "SHEET_ONE"
.ActiveWorkbook.Worksheets(1).Cells(1,1) = "I believe i can fly !!!"
EndWith
Local $filename = #WorkingDir&"\saveas_excel.xls"
$oExcel.Application.DisplayAlerts = 0
$oExcel.Application.ScreenUpdating = 0
$oExcel.ActiveWorkBook.SaveAs($filename, 1, Default, Default, Default, Default, 2, 1)
$oExcel.Quit
More information (in french) on http://www.autoitscript.fr/forum/viewtopic.php?t=3272&f=11

Resources