I'm trying to set worksheet permissions for an XLSM file using EPPlus but it seems I can only set the default protection level, individual protections are not being set. For the record, I'm trying to accomplish programmatically method 1 in this article. Here's the code I'm using:
using (var p = new ExcelPackage("output.xlsm"))
{
var ws = p.Workbook.Worksheets["MySheet"];
// Set some cell values here
// Filtering, sorting, protection
ws.Cells[7, 1, 10, 5].AutoFilter = true;
ws.View.FreezePanes(7, 1);
ws.ProtectedRanges.Add("FilteredCells", new ExcelAddress(7, 1, 10, 5));
// Worksheet protection
ws.Protection.AllowAutoFilter = true;
ws.Protection.AllowDeleteColumns = false;
ws.Protection.AllowDeleteRows = false;
ws.Protection.AllowEditObject = false;
ws.Protection.AllowEditScenarios = false;
ws.Protection.AllowFormatCells = false;
ws.Protection.AllowFormatColumns = false;
ws.Protection.AllowFormatRows = false;
ws.Protection.AllowInsertColumns = false;
ws.Protection.AllowInsertHyperlinks = false;
ws.Protection.AllowInsertRows = false;
ws.Protection.AllowPivotTables = false;
ws.Protection.AllowSelectLockedCells = false;
ws.Protection.AllowSelectUnlockedCells = true;
ws.Protection.AllowSort = true;
ws.Protection.IsProtected = true;
ws.Protection.SetPassword("hunter2");
p.SaveAs(new FileInfo("output.xlsm"));
}
This runs without errors, but when I open the file in Excel, or load it back into EPPlus, I find that different protection options have been applied:
AllowAutoFilter = false
AllowDeleteColumns = false
AllowDeleteRows = false
AllowEditObject = true
AllowEditScenarios = true
AllowFormatCells = false
AllowFormatColumns = false
AllowFormatRows = false
AllowInsertColumns = false
AllowInsertHyperlinks = false
AllowInsertRows = false
AllowPivotTables = false
AllowSelectLockedCells = true
AllowSelectUnlockedCells = true
AllowSort = false
IsProtected = true
These obviously aren't the permissions I set before, so how can I make sure they are set correctly? Everything else is saved correctly.
Here is the source:
https://github.com/pruiz/EPPlus/blob/master/EPPlus/ExcelSheetProtection.cs
Setting the IsProtected property is overwriting your choices:
public bool IsProtected
{
get
{
return GetXmlNodeBool(_isProtectedPath, false);
}
set
{
SetXmlNodeBool(_isProtectedPath, value, false);
if (value)
{
AllowEditObject = true;
AllowEditScenarios = true;
}
else
{
DeleteAllNode(_isProtectedPath); //delete the whole sheetprotection node
}
}
}
Move your IsProtected = true call to the start of the code or handle however you want, but you are accidently overriding your previous choice. I would look at the properties at that link to see which ones are going to override your existing selections.
Related
I have application where i am trying to make checkbox checked based on value i get from string. String name is called aktivan and returns values Da or Ne, i checked with messagebox and values are here and valid. If value are Da it need to check checkbox but it doesn't work.
chkAktivan.Checked = aktivan == "Da" ? true : false; // doesn't work
chkAktivan.Checked = true; // working
chkAktivan.Checked = false; // working
Same is for radio, based on string values Muški or Ženski it need to set values but also does't working all time its checking Ženski radio.
if (spol == "Muški")
{
radioMuski.Checked = true;
radioZenski.Checked = false;
}
else
{
radioMuski.Checked = false;
radioZenski.Checked = true;
}
You should trim the values before using them, like this.
if (spol.Trim() == "Muški")
{
radioMuski.Checked = true;
radioZenski.Checked = false;
}
else
{
radioMuski.Checked = false;
radioZenski.Checked = true;
}
And also this.
chkAktivan.Checked = aktivan == "Da" ? true : false;
To this:
chkAktivan.Checked = aktivan.Trim() == "Da" ? true : false;
partial answer
For the first part of your question, regarding this line:
chkAktivan.Checked = aktivan == "Da" ? true : false;
Try changing it to:
chkAktivan.Checked = (aktivan == "Da" ? true : false);
OR MORE SIMPLY:
chkAktivan.Checked = "Da".Equals(aktivan);
Design:
If i don't have any land component price/flight prices to be added, i want the system to dispose the unused controls and move up to fill in the empty spaces, but somehow or rather, it became like this.
Result:
if (bf.landComponent != 0.00m)
{
lblLandComponent.Text = "" + bf.landComponent;
lblLandComponent.Visible = true;
lblLandComponentL.Visible = true;
}
else
{
lblLandComponent.Dispose();
lblLandComponentL.Dispose();
}
if (bf.flightComponent != 0.00m)
{
lblFlightComponent.Text = "" + bf.flightComponent;
lblFlightComponent.Visible = true;
lblFlightComponentL.Visible = true;
}
if (bf.unitSales != 0.00m)
{
lblUnitSales.Text = "" + bf.unitSales;
lblUnitSales.Visible = true;
lblUnitSalesL.Visible = true;
}
if(bf.rentalCar!=0.00m)
{
lblCT.Visible = true;
lblRentalCar_L.Visible = true;
lblRentalCar.Visible = true;
lblRentalCar.Text = "" + bf.rentalCar;
}
if (bf.discount != 0.00m)
{
lblDiscount.Text = "" + bf.discount;
lblDiscountL.Visible = true;
lblDiscount.Visible = true;
}
if(bf.packageInclusion!="")
{
lblPackageInclusion.Text = bf.packageInclusion;
lblPackageInclusion.Visible = true;
lblPackageInclusionL.Visible = true;
}
//BF is a class object stored in a session that i put from the previous page.
Is there something wrong?
The Dispose method is not for the thing you want. Check in the docs to see what it really does.
When you want to hide a control, try setting their Visibility to false, or try removing them from their parent container control.
Conditionally setting their Visibility to true is not enough. In 99% of cases they would be visible anyways, since that's the default value for visibility. You must ensure to either set their initial Visibility to false, or add else clause that will do that.
I use Evernote C# API. I understand how filters working.
ENNoteStoreClient store = ENSessionAdvanced.SharedSession.PrimaryNoteStore;
SyncState currentState = store.GetSyncState();
int currentUpdateCount = currentState.UpdateCount;
if (currentUpdateCount > latestUpdateCount)
{
latestUpdateCount = currentUpdateCount;
// Here synchronization code
}
I have latestUpdateCount and how I can get notes with sequence number >= this number?
You'll want to use GetFilteredSyncChunk using code something like the following:
List<SyncChunk> syncBlocks = new List<SyncChunk>();
int maxEntries = 250;
// These are sample filter settings; you should use what's appropriate for you based on
// what data you want returned in your note objects.
SyncChunkFilter filter = new SyncChunkFilter();
filter.IncludeNotes = true;
filter.IncludeNoteAttributes = true;
filter.IncludeNotebooks = true;
filter.IncludeTags = false;
filter.IncludeSearches = false;
filter.IncludeResources = false;
filter.IncludeLinkedNotebooks = false;
filter.IncludeExpunged = false;
filter.IncludeNoteApplicationDataFullMap = false;
filter.IncludeResourceApplicationDataFullMap = false;
filter.IncludeNoteResourceApplicationDataFullMap = false;
do
{
SyncChunk chunk = store.getFilteredSyncChunk(currentUpdateCount, maxEntries, filter);
if (chunk == null)
{
return null; // This can happen if there is a "503 - Service unavailable" error accessing this person's Evernote info
}
syncBlocks.Add(chunk);
currentUpdateCount = chunk.ChunkHighUSN;
} while (currentUpdateCount < serverSyncState.UpdateCount);
foreach (SyncChunk chunk in syncBlocks)
{
if (chunk != null && chunk.Notes != null)
{
foreach (Note chunkNote in chunk.Notes)
{
// do something with the retrieved chunkNote object
}
}
}
I am trying to create a tab via the DocuSign API with the following requirements:
Optional
Text
Anchored
Shared
Has a Default Value
However, when i set the value of the tab before composing and sending the envelope, the tab will not be editable to any of the Recipients. See code below:
private static Tab buildOptionalInputTab(String recId, String docId, String defaultValue)
{
Tab tab = new Tab();
tab.RecipientID = recId;
tab.AnchorTabItem = new AnchorTab { AnchorTabString = "Tracking #:" };
tab.AnchorTabItem.XOffset = 135;
tab.AnchorTabItem.YOffset = -8;
tab.DocumentID = docId;
tab.Type = TabTypeCode.Custom;
tab.CustomTabRequiredSpecified = true;
tab.CustomTabRequired = false;
tab.CustomTabType = CustomTabType.Text;
tab.Name = "Tracking #";
tab.SharedTabSpecified = true;
tab.SharedTab = true;
tab.Value = defaultValue; //REMOVE THIS LINE AND IT WORKS
return tab;
}
Add tab.Locked = false; to your SOAP request and you should be able to set the default value while also making it editable.
i am trying to set a value from server side in this code. i have a textbox to enter ticket number and when the ticket is validated and activated, i want the used property of this particulare ticket to be changed to true.
i have this code :
TicketBLL Tickets = new TicketBLL();
ClientDeviceBLL Devices = new ClientDeviceBLL();
if (String.IsNullOrEmpty(txtTicket.Text))
{
CVUsed.Visible = false;
CVUsed.Enabled = false;
CVMember.Enabled = false;
CVMember.Visible = false;
CVInValid.Enabled = false;
CVInValid.Visible = false;
lblMessages.Text = MessageFormatter.GetFormattedErrorMessage("You can login using a Ticket Number.");
txtTicket.Focus();
}
else
{
Ticket = Tickets.GetTicketByTicketNumber(txtTicket.Text);
////// we must enter the value of the correct SN and the Client ID
Device = Devices.GetClientDeviceBySN(txtSN.Text , Convert.ToInt32(txtClientID.Text));
if (Ticket != null)
{
//Correct Ticket number
CVInValid.Visible = false;
CVInValid.Enabled = false;
if (Ticket.Used == true)
{
//ticket was used, internet forbidden
CVUsed.Visible = true;
CVUsed.Enabled = true;
CVMember.Enabled = false;
CVMember.Visible = false;
CVUsed.IsValid = false;
}
else
{
//if exists but not used, Ticket accepted
//check if device is a member if client divices
if (Device != null)
{
//internet access garanteed
CVUsed.Visible = false;
CVUsed.Enabled = false;
CVMember.Enabled = false;
CVMember.Visible = false;
CVUsed.IsValid = true;
CVMember.IsValid = true;
//here is my error.
//ticket.used is not changing in the database so the next
//time he enters the same ticket number it would go through
//again.
Ticket.Used = true;
Response.Redirect("http://www.google.com");
}
else
{
//device not member, internet access forbidden
CVMember.Enabled = true;
CVMember.Visible = true;
CVUsed.Visible = false;
CVUsed.Enabled = false;
CVUsed.IsValid = true;
CVMember.IsValid = false;
}
}
}
else
{
//Ticket Number is not valid
CVUsed.Visible = false;
CVUsed.Enabled = false;
CVMember.Enabled = false;
CVMember.Visible = false;
CVInValid.Enabled = true;
CVInValid.Visible = true;
CVInValid.IsValid = false;
}
}
how can i automatically update the ticket.used value in the database?!
Without making a connection to database you cannot update the value of ticket.used. If you want to know how to connect to database and update, use stored procedures of direct queries to do your work. Take a look at this.