I'm trying to import spreadsheet data into a CMS, but there are around 100 comments on various cells throughout the 4000+ row spreadsheet that we would like to import also. Is there a function or macro that will copy the comment content into a cell? (not as a comment, just as plain text)
In Openoffice API the interface XSheetAnnotationsSupplier provides a method getAnnotations. Using this it is possible to get all sheet annotations together with their positions. The Position is the address of the cell in which the annotation is placed:
sub getAnnotations()
oThisWorkbook = ThisComponent
oActiveSheet = oThisWorkbook.CurrentController.ActiveSheet
oAnnotations = oActiveSheet.Annotations
for each oAnnotation in oAnnotations
lColumn = oAnnotation.Position.Column
lRow = oAnnotation.Position.Row
sText = oAnnotation.String
oCell = oActiveSheet.getCellByPosition(lColumn, lRow)
msgbox oCell.AbsoluteName & " has annotation: " & sText
next
end sub
So you have the annotations (comments) and their cells.
Now you have to decide what you wants to do with that. As said in my comment already, simply appending the annotations to the cell contents is not a good idea in my opinion. That will possibly make the cell content unreadable for further processing.
I have a named range that current refers to A1:I8 in a worksheet. I would like to change it to refer to a larger part of the worksheet. Does anyone know of a method in Aspose that does this? Or a method that lets me delete the existing range in Aspose?
You may try the following sample code for your reference:
Workbook workbook = new Workbook("e:\\test\\Book1.xlsx");
Worksheet sheetRef = workbook.Worksheets[0];
NameCollection names = workbook.Worksheets.Names;
Name name = names["MyRange"];
name.RefersTo = "=A1:J10";
Given one table in SQL Server which holds consolidated data from three source tables including one column called OFFICE which differentiates the records from each other.
The three source tables hold data from three offices.
I want to create an Excel file dynamically which will have 3 sheets in one workbook based on the three different different offices (ex. office1, office2, office3) resulting in each sheet containing the relevant data according to its office.
Please recommend an approach using dynamic Excel destination in SSIS as I don't want to use an approach which creates a template file and then copies that template to destination excel file.
While this can be accomplished using a scipt task and C#, a far easier solution is demonstrated at
http://www.rafael-salas.com/2006/12/import-header-line-tables-_116683388696570741.html
and the follow-up
http://www.rafael-salas.com/2008/03/ssis-and-dynamic-excel-destinations_01.html#!
But to summarize the relevant details, you need to use an 'Execute SQL Task' to dynamically create the sheet at runtime prior to using it as a destination.
Create a new variable to hold the Sheet name and set this variable to the Office you are working with as you iterate through them.
Also, create a variable to hold the Create table statement that will create each sheet.
For example,
"CREATE TABLE "+ #[User::SheetName] + "(HeaderID INTEGER, HeaderName NVARCHAR(50), LineID INTEGER, LineName NVARCHAR(50), LineDetails NVARCHAR(50))"
and Set the SQLSourceType Property of the Execute SQL task inside of the For Each container to Variable and choose the Variable you created to hold the create statement.
In the Excel Destination Component, Change the data access mode to ‘Table Name or View Name Variable’ and choose the sheet name variable you created from the variable dropdown list.
I have several SSIS packages that perform a similar function. A single Excel file consists of multiple worksheets with each worksheet populated by results from a separate SQL query. Here are the basic generic steps I applied. Before you begin, make certain you create a connection manager for both the database to be applied and the output Excel file.
1) Create a Script task in Control flow and populate it like the following. Here I am creating the Excel file along with the worksheets it will contain. (Worksheets should never include any spaces or special characters.) My code below is in C#.
using System;
using System.IO;
using System.Collections.Generic;
using System.Data;
using System.Text;
using Excel = Microsoft.Office.Interop.Excel;
using Microsoft.SqlServer.Dts.Runtime;
namespace ST_87e8d62a054b4e16b60297154afc19d8.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
public void Main()
{
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.ApplicationClass();
xlWorkBook = xlApp.Workbooks.Add(misValue);
//Create First worksheet
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
xlWorkSheet.Name = "Names";
//Define column headers for "RawData" WorkSheet
xlWorkSheet.Cells[1, 1] = "First Name";
xlWorkSheet.Cells[1, 2] = "Last Name";
xlWorkSheet.Cells[1, 3] = "Title";
// Create Second Worksheet
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(2);
xlWorkSheet.Name = "Addresses";
//Define column headers for "CCDN" WorkSheet
xlWorkSheet.Cells[1, 1] = "Street";
xlWorkSheet.Cells[1, 2] = "City";
xlWorkSheet.Cells[1, 3] = "State";
xlWorkSheet.Cells[1, 4] = "Zip";
xlWorkSheet.Cells[1, 5] = "Country";
string Filename = "C:\\MyFile.xls";
if (File.Exists(Filename))
{
File.Delete(Filename);
}
xlWorkBook.SaveAs(Filename, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
Dts.TaskResult = (int)ScriptResults.Success;
}
2) Create in your database two tables that will be populated temporarily. That is, one table will be populated for the results of the first worksheet and the second table will be populated for the results of the second worksheet. It is a good naming approach to preface the names of each table with "Working_" so that you know the purpose of each. I took the approach of using tables instead of views is because I like to sort (ORDER BY) my results, which cannot be done with a view.
3) Add to the SSIS package two Execute SQL Tasks under Control Flow. The first task will run an INSERT SQL statement that will populate the first table you just created and the second task will run another INSERT SQL statement that will populate the second table just created.
4) Add to the SSIS package two Data Flow tasks under Control Flow. The first will be for populating the first worksheet and the second for populating the second worksheet.
5) Select the first Data Flow task and add to it under Data Flow an OLE DB Source where you will define the OLE DB conenction manager (your database) and then the table or view. Select the first new table created. Make certain all of the columns of interest are selected and that you can perform a preview.
6) Add a Data Conversion flow task and then an Excel Destination flow task.
7) Repeat steps 5 and 6 for the second worksheet and table.
8) Finally under Control Flow add an Excel SQL Task that will remove the contents of the two Working tables. You do not want the old contents to be included the next time the package is run.
Now, if you want to play around with formatting of the Excel file after it is completed and impress your manager, you can also do that in code with a final Task Script (also using C#). The nice part about this approach is that you are not having to apply any special formatting functions in your SQL, Excel is doing all the work. You could actually include the formatting in Step 1 and as soon as you copy the data over in the following steps, it is automatically formatted. As with any report output, there is not point in making SQL perform formatting steps (adding additional work to the database server) when it is more efficient to let Excel or SSRS do what they do best.
public void Main()
{
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
Excel.Range xlRange;
xlApp = new Excel.ApplicationClass();
string Filename = "C:\\MyFile.xls";
xlWorkBook = xlApp.Workbooks.Open(FileName, 0, false, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
//Format cells in Names worksheet
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
//Set the header range in bold font
xlRange = xlWorkSheet.get_Range("a1", "p1");
xlRange.Font.Bold = true;
xlRange.WrapText = true;
//Freeze first row listing headers
xlWorkSheet.Application.ActiveWindow.SplitRow = 1;
xlWorkSheet.Application.ActiveWindow.FreezePanes = true;
//Auto adjust the width of each column
xlWorkSheet.Columns.AutoFit();
xlRange = xlWorkSheet.get_Range("c1", "j6467");
xlRange.Cells.Locked = false;
xlRange.Interior.Color = 65535;
xlRange = xlWorkSheet.get_Range("o1", "p6467");
xlRange.Cells.Locked = false;
xlRange.Interior.Color = 65535;
//Do not alert when saving changes to Excel file.
xlWorkBook.Application.DisplayAlerts = false;
//Save Excel file modifications
xlWorkBook.Save();
//Close workbook and application
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
//Release from cache.
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
//Set formatting of percent cells
xlRange = xlWorkSheet.get_Range("d3", "d7");
xlRange.NumberFormat = "###,###%";
//Define the top left cell and bottom right cell of the table in the Excel worksheet
xlRange = xlWorkSheet.get_Range("c1", "c7");
//Draw grid of thin line around each cell in table
xlRange.BorderAround(Excel.XlLineStyle.xlContinuous, Excel.XlBorderWeight.xlThin, Excel.XlColorIndex.xlColorIndexAutomatic, 1);
//Draw thick border around entire table
xlRange = xlWorkSheet.get_Range("a1", "d7");
xlRange.BorderAround(Excel.XlLineStyle.xlContinuous, Excel.XlBorderWeight.xlThick, Excel.XlColorIndex.xlColorIndexAutomatic, 1);
//Right justify columns B and C
xlRange = xlWorkSheet.get_Range("b3", "c7");
xlRange.HorizontalAlignment = Excel.XlHAlign.xlHAlignRight;
//Do not alert when saving changes to Excel file.
xlWorkBook.Application.DisplayAlerts = false;
//Save Excel file modifications
xlWorkBook.Save();
//Close workbook and application
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
//Release from cache.
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
Dts.TaskResult = (int)ScriptResults.Success;
}
And that's about it. Notice that just for the purpose of this example, I'm hardcoding the filename. But in my actual code I am applying a User variable which is then populated by another SQL statement pulling the name from another database table. For best practices, it a good idea to keep your SSIS packages entirely table-driven. That way, any changes made to names and locations are made in a database table in a record specific to your SSIS package... avoiding any need to update your SSIS package and go through the dev to QA to production lifecycle again.
Hope this helps and please let me know if you have any questions.
I have some shape data (a series of kml files in the column of a fusion table and or database) and I want to merg it with another table that contains latitude longitude points. Basically I want some way of determining if a given lat lon point is contained within on of the kml shapes, and if so save a reference to that row.
I though perhaps there was a way to do this from within fusion tables, but if not, perhaps there is a way to loop through each kml and test if the lat lon point is contained within it. I understand this in not terribly efficient.
Any help, algorithm, service etc would be great.
The Fusion Tables SQL API has a ST_INTERSECTS operator but will only find points within either a CIRCLE or a RECTANGLE. GMap V3 has a geometry library which has a poly.containsLocation() method which I think will work for arbitrary polygons. See: GoogleMap geometry/poly library
P.S. I realize this does not work for KML files, but they do contain the polygon points which could be turned into GMAP polygons
This is probably long since solved, but as I had a similar problem I thought I'd post my solution.
I had two Fusion tables i) address & data and ii) polygons & data. I wanted to be able to easily query to find all addresses within one or more of the polygons. I could have done this realtime via my mapping webpage, but decided it was better to lookup the relevant polygon once in advance and then use this data to do my mapping queries (faster and easier to specify multiple polygons in the web interface).
So, I exported my table i) with the addresses to google sheets, and created a short simple script that checked which polygon the address was in and wrote it back to the google sheet. Then I updated my fusion table i).
I had a data set of nearly 3000 addresses and 2000 polygons so it timed out a few times and a had a couple of address errors, but this was easy to fix and I just set the script to run from the first row that hadn't been updated. Note that this won't work if the polygons overlap each other, but mine didn't as they were geographic boundaries ;-)
The code I used is below and also on gist here. You obviously need to update the table ID, and probably need to do something with OAuth (which I didn't quite understand but followed google's instructions and got it done).
// replace with your fusion table's id (from File > About this table)
var TABLE_ID = 'xxxxxxxxxx';
// first row that has data, as opposed to header information
var FIRST_DATA_ROW = 2;
var FIRST_DATA_COLUMN = 11;
var LAT_COLUMN = 1;
var LNG_COLUMN = 2;
var SA2_COLUMN = 6;
var SA3_COLUMN = 7;
/**
* Uses a lat and lng data in google sheets to check if an address is within a kml polygon
* in a list of KML polygons in fusion (in this case ABS/ASGC SA2 and SA3 regions, but could be any polygon)
* the function then stores the ID/name of the relevant polygon in google sheets
* I could check this data in realtime as I render maps, but as it doesn't changed, figure its better to just record
* which polygon each address pertains to so its quicker and easier to search (in particular it mades it easier to write a query
* which identifies all the address within multiple polygons)
* in this case I had 3000 rows so it exceeded maximum execution times, so I just updated the first data row a couple of times
* when the execution time exceeded.
*/
function updateSA2ID() {
var tasks = FusionTables.Task.list(TABLE_ID);
var sqlResponse = '';
// Only run if there are no outstanding deletions or schema changes.
if (tasks.totalItems === 0) {
var sheet = SpreadsheetApp.getActiveSheet();
var latLngData = sheet.getRange(FIRST_DATA_ROW, FIRST_DATA_COLUMN, sheet.getLastRow(), sheet.getLastColumn());
i = 1;
// Loop through the current current sheet
for (i = 1; i <= latLngData.getNumRows(); i++) {
// cross reference to Fusion table
lat = latLngData.getCell(i,LAT_COLUMN).getValue();
lng = latLngData.getCell(i,LNG_COLUMN).getValue();
sqlString = "SELECT 'SA2 Code', 'SA3 Code' FROM " + TABLE_ID + " WHERE ST_INTERSECTS(geometry, CIRCLE(LATLNG(" + lat + ", " + lng + "),1)) ";
//Browser.msgBox('Lat ' + lat + ' Lng ' + lng + '; ' + sqlString, Browser.Buttons.OK);
sqlResponse = FusionTables.Query.sql(sqlString);
//Browser.msgBox('SQL Response ' + sqlResponse, Browser.Buttons.OK);
latLngData.getCell(i,SA2_COLUMN).setValue(sqlResponse.rows[0][0]); // set SA2
latLngData.getCell(i,SA3_COLUMN).setValue(sqlResponse.rows[0][1]); // set SA3
}
}
else {
Logger.log('Skipping row replacement because of ' + tasks.totalItems + ' active background task(s)');
}
};
In my Access VBA I have hyperlink, which is using the following way to link to cell:
oSheet.Cells(1, i).Formula = "=HYPERLINK(""#Sheet2!E6"", """ & !TestCase & """)"
However, instead of E6, I want to use row,col notation, since all my internal application logic is using Cells/rows/cols.
Thanks.
Instead of Formulause FormulaR1C1(Row / Column format)
Here are two examples:
Set the formula of your cells to =$B$1 :
oSheet.Cells(1, i).FormulaR1C1 = "=R1C2"
Set the formula of A1 to =C2, A2 to =C3 etc.:
Range("A1:A10").FormulaR1C1 = "=R[1]C[2]"