How do I selectively share data with clients, so that they only see their own data, and not of their competitors? - vba

I have data like this in my Excel 2013 workbook
Table 1:
Col A Col B Col B
1 Client 1 ..... 123
2 Client 1 ..... 456
3 Client 1 ..... 99
4 Client 2 ..... 324
5 Client 2 ..... 989
6 Client 3 ..... 234
7 Client 3 ..... 23
I am using this Table 1 for a client specific report elsewhere in the excel. e.g.
Client Report: Client 1
Col A Col B Col C Col D
1 Client 1 123 456 99
The cell A1 in the report is a data validation dropdown containing the names of the Clients. I can change that dropdown to Client 2
Client Report: Client 2
Col A Col B Col C Col D
1 Client 2 324 989
What I want to be able to do is send out one file to all clients, which contains the Client Report, but each Client should only be able to see their own data. As a bonus, each client should also not be able to see which other clients are on the list (i.e. in the file that Client 1 receives, he/she should not have access to the numbers of Client 2 and Client 3, and as a bonus, should not even see the names Client 2 and Client 3)
I have an option of creating these files manually, for each client. I am looking for a way to hide data in a file depending on which Client it is for, and thus sending out the same file to multiple clients (I have ~30 clients, so the manual process will be error prone and a pain). I don't want to create 30 separate files or sheets if I can help it. The ideal way would be to build a 'master' option, which gives me access to all data, but not to the client who I send this out to. However, data confidentiality is super critical, and if password protection in Excel Workbooks is questionable, then I would not want this option, and I will go back to manual :)
Also, even though I am only looking for vanilla Excel solutions (I can't rely on my clients to have addons installed or install one just for the sake of this), if you do know of interesting ways to address this kind of a problem with addons, please do comment/answer.
Thanks!

As Steven Martain said, there is NO SECURITY in Excel. You can password-protect your Workbook, but the password can be broken in no time at all. Instead split your file into several separate files. Please see this link for an idea of how to do this.
http://www.rondebruin.nl/win/s3/win006.htm
Then, simply email the different files to different recipients/clients/people. See this link for an idea of how to do that.
http://www.rondebruin.nl/win/s1/outlook/amail6.htm

It is not possible to do it without coding/VB. However, you can use InstaRow ( check here). Which is perfect tool for this problem. You can signup with email id ( and your clients). They will see exactly their portion.
They can even change data easily.

Posting #StevenMartin 's answer from the comments above, as it seems to the way to go about it
"Write a macro to spit out 30 workbooks - a simple search would tell you excel password protection can be broken in seconds"

Related

Converting to Pandas DataFrame

I have a row which looks like this:
{0: '{"Paradigms":["Agile Software Development","Scrum","DevOps","Serverless Architecture"],"Platforms":["Kubernetes","Linux","Windows","Eclipse","PagerDuty","Apache2","Docker","AWS EC2","Amazon Web Services (AWS)","Sysdig","Apache Kafka","AWS Lambda","Azure","OpenStack"],"Storage":["AWS S3","MongoDB","Cassandra","MySQL","PostgreSQL","AWS DynamoDB","Spring Data MongoDB","AWS RDS","MySQL/MariaDB","Datadog","Memcached"],"Languages":["Java","PHP","SQL","Bash","Perl","JavaScript","Python","C#","Go"],"Frameworks":["Ruby on Rails (RoR)","AWS HA",".NET","Serverless Framework","Selenium","CodeIgniter","Express.js"],"Other":["Cisco","Content Delivery Networks (CDN)","Kubernetes Operations (Kops)","Prometheus","VMware ESXi","Bash Scripting","Scrum Master","Infrastructure as Code","Performance Tuning","Serverless","System Administration","Linux System Administration","Code Review"],"Libraries/APIs":["Node.js","Jenkins Pipeline","jQuery","React","Selenium Grid"],"Tools":["Jenkins","Bitbucket","GitHub","AWS ECS","AWS IAM","Amazon CloudFront CDN","Terraform","AWS CloudFormation","Git Flow","Artifactory","Nginx","Grafana","Zabbix","Docker Compose","AWS CLI","AWS ECR","Chef","Jira","Git","Postfix","MongoDB Shell","Wowza","Amazon SQS","AWS SES","Subversion (SVN)","TeamCity","Microsoft Visual Studio","Google Kubernetes Engine (GKE)","VMware ESX","Fluentd","Sumo Logic","Slack","Apache ZooKeeper","AWS Fargate","Ansible","ELK (Elastic Stack)","Microsoft Team Foundation Server","Azure Kubernetes Service (AKS)"]}',
1: '{"Platforms":["Debian Linux","Windows","Linux","NetBeans"],"Storage":["MySQL","Morphia","MongoDB","Oracle SQL","PostgreSQL","IBM DB2"],"Languages":["HTML5","CSS","Java","JavaScript","C++","Less","XPath","PHP","R","XSLT","XUL"],"Frameworks":["GWT","JUnit","Hibernate","AngularJS","JavaServer Pages (JSP)","Spring","JNI","Selenium","ASP.NET","Apache Velocity"],"Other":["Ajax","COM"],"Libraries/APIs":["HTML5 Canvas","Digester","JAXB","Java Servlets","Node.js","Jackson","JDBC","Standard Template Library (STL)","FFTW","ODBC","OpenGL","XStream"],"Tools":["Subversion (SVN)","Apache Ant","Mime4J","YourKit","IntelliJ IDEA","Apache Tomcat","Git","GCC","Cygwin","Maven","Eclipse IDE","UJAC","Flash","Mathematica","Perforce","CVS","GDB","Grunt","JDeveloper"]}',
2: '{"Platforms":["Firebase","XAMPP"],"Storage":["JSON"],"Languages":["CSS","Sass","JavaScript","TypeScript","HTML5","CSS3"],"Frameworks":["Angular","Bootstrap 3+","Jasmine"],"Libraries/APIs":["jQuery","Pure CSS"],"Tools":["Git","NPM","GitHub","Atom","Angular CLI","Photoshop CS5","Karma"]}',
3: '{"Paradigms":["Agile","CQRS","Azure DevOps"],"Platforms":["Debian Linux","Windows","Azure","Red Hat Linux","Visual Studio Code","Docker"],"Storage":["PostgreSQL","SQL Server 2016"],"Languages":["Python","JavaScript","C#","SQL","Java","C","C++","Bash","HTML"],"Frameworks":["AngularJS",".NET","Qt","Ruby on Rails (RoR)","Hibernate","Spring",".NET Core"],"Other":["IIS","Google Material Design","EDA","Sagas","Visual Studio Team Services (VSTS)"],"Libraries/APIs":["jQuery","Ruby on Rails API"],"Tools":["Microsoft Visual Studio","Qt Creator","Mercurial","Git","Jira","Terraform","Jenkins","Atom","Vim Text Editor","Eclipse IDE","Maven","SonarQube","Azure Kubernetes Service (AKS)"]}',
How would I convert this so that each key (Paradigms, Platforms, etc.) becomes a column in a pandas dataframe? I've already tried a few things...
Am pretty stuck so would really appreciate some help!:)
Expected output would be something like this, but with additional columns for additional keys after Paradigms (like Storage, Tools, Languages, etc.):
Paradigms Platforms Storage Languages ...
0 0 0 0
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
this is the value of talentpool_subset['skills'][0] (which is the same as talentpool_df, just a subset of the bigger dataframe):
'{"Paradigms":["Agile Software Development","Scrum","DevOps","Serverless Architecture"],"Platforms":["Kubernetes","Linux","Windows","Eclipse","PagerDuty","Apache2","Docker","AWS EC2","Amazon Web Services (AWS)","Sysdig","Apache Kafka","AWS Lambda","Azure","OpenStack"],"Storage":["AWS S3","MongoDB","Cassandra","MySQL","PostgreSQL","AWS DynamoDB","Spring Data MongoDB","AWS RDS","MySQL/MariaDB","Datadog","Memcached"],"Languages":["Java","PHP","SQL","Bash","Perl","JavaScript","Python","C#","Go"],"Frameworks":["Ruby on Rails (RoR)","AWS HA",".NET","Serverless Framework","Selenium","CodeIgniter","Express.js"],"Other":["Cisco","Content Delivery Networks (CDN)","Kubernetes Operations (Kops)","Prometheus","VMware ESXi","Bash Scripting","Scrum Master","Infrastructure as Code","Performance Tuning","Serverless","System Administration","Linux System Administration","Code Review"],"Libraries/APIs":["Node.js","Jenkins Pipeline","jQuery","React","Selenium Grid"],"Tools":["Jenkins","Bitbucket","GitHub","AWS ECS","AWS IAM","Amazon CloudFront CDN","Terraform","AWS CloudFormation","Git Flow","Artifactory","Nginx","Grafana","Zabbix","Docker Compose","AWS CLI","AWS ECR","Chef","Jira","Git","Postfix","MongoDB Shell","Wowza","Amazon SQS","AWS SES","Subversion (SVN)","TeamCity","Microsoft Visual Studio","Google Kubernetes Engine (GKE)","VMware ESX","Fluentd","Sumo Logic","Slack","Apache ZooKeeper","AWS Fargate","Ansible","ELK (Elastic Stack)","Microsoft Team Foundation Server","Azure Kubernetes Service (AKS)"]}'````
Since I can't comment yet, here's what I've come up with. From what I understand "Paradigms, Platforms, etc" will be column names and the values will become rows.
Assign your row above as dictionary (dict). Get only the values to create list, then create a dataframe from that list.
import json
data = [ json.loads(v) for v in dict.values()]
df = pd.DataFrame(data)
Hope it helps.

Execute UITests In Different Order

I have many test methods added to my project. I want to test by changing the order of tests each time.
For example if i have 3 test methods.
I want to run 6 tests like
i) 1 2 3
ii) 1 3 2
iii) 2 1 3
iv) 3 1 2
v) 2 3 1
vi) 3 2 1
How can i achive this in XCode?
Note: It is in means like test 1 creates setup things for test 2. Input or UI somethings like that. Thats why i need to keep a sequence
Tests should not have any effect on state at all. And they should not depend on previous state either.
Running 1, 2, 3. Should have the exact same results as running 3, 2, 1.
Before running, each test should set up the required conditions that it is testing.
After running, each test should tear down the system so that there is nothing hanging around for the next test.
So, in answer to your question, I don't know if it's possible to specify an order... but you really shouldn't care what order they run in. If you do then that's a sign that your tests are not independent of each other.

Getting the images produced by AzureML experiments back

I have created a toy example in Azure.
I have the following dataset:
amounts city code user_id
1 2.95 Colleferro 100 999
2 2.95 Subiaco 100 111
3 14.95 Avellino 101 333
4 14.95 Colleferro 101 999
5 14.95 Benevento 101 444
6 -14.95 Subiaco 110 111
7 -14.95 Sgurgola 110 555
8 -14.95 Roma 110 666
9 -14.95 Colleferro 110 999
I create an AzureML experiment that simply plots the column of the amounts.
The code into the R script module is the following:
data.set <- maml.mapInputPort(1) # class: data.frame
#-------------------
plot(data.set$amounts);
title("This title is a very long title. That is not a problem for R, but it becomes a problem when Azure manages it in the visualization.")
#-------------------
maml.mapOutputPort("data.set");
Now, if you click on the right output port of the R script and then on "Visualize"
you will see the Azure page where the outputs are shown.
Now, the following happens:
The plot is stucked into an estabilished space (example: the title is cut!!!)
The image produced is a low resolution one.
The JSON produced by Azure is "dirty" (making the decoding in C# difficult).
It seems that this is not the best way to get the images produced by the AzureML experiment.
Possible solution: I would like
to send the picture produced in my experiment to a space like the blob
storage.
This would be also a great solution when I have a web-app and I have to pick the image produced by Azure and put it on my Web App page.
Do you know if there is a way to send the image somewhere?
To saving the images into Azure Blob Storage with R, you need to do two steps, which include getting the images from the R device output of Execute R Script and uploading the images to Blob Storage.
There are two ways to implement the steps above.
You can publish the experiment as a webservice, then get the images with base64 encoding from the response of the webservice request and use Azure Blob Storage REST API with R to upload the images. Please refer to the article How to retrieve R data visualization from Azure Machine Learning.
You can directly add a module in C# to get & upload the images from the output of Execute R Script. Please refer to the article Accessing a Visual Generated from R Code in AzureML.
You can resize the image in following way:
graphics.off()
png("myplot.png",width=300,height=300) ## Create new plot with desired size
plot(data.set);
file.remove(Sys.glob("*rViz*png")) ## Get rid of default rViz file

getgroup() is very slow

I am using the function getgroup() to read all of the groups of a user in the active directory.
I'm not sure if I'm doing something wrong but it is very very slow. Each time it arrives at this point, it takes several seconds. I'm also accessing the rest of Active directory using the integrated function of "Accountmanagement" and it executes instantly.
Here's the code:
For y As Integer = 0 To AccountCount - 1
Dim UserGroupArray As PrincipalSearchResult(Of Principal) = UserResult(y).GetGroups()
UserInfoGroup(y) = New String(UserGroupArray.Count - 1) {}
For i As Integer = 0 To UserGroupArray.Count - 1
UserInfoGroup(y)(i) = UserGroupArray(i).ToString()
Next
Next
Later on...:
AccountChecker_Listview.Groups.Add(New ListViewGroup(Items(y, 0), HorizontalAlignment.Left))
For i As Integer = 0 To UserInfoGroup(y).Count - 1
AccountChecker_Listview.Items.Add(UserInfoGroup(y)(i)).Group = AccountChecker_Listview.Groups(y)
Next
Item(,) contains my normal Active directory data that I display Item(y, 0) contain the username.
y is the number of user accounts in AD. I also have some other code for the other information in this loop but it's not the issue here.
Anyone know how to make this goes faster or if there is another solution?
I'd recommend trying to find out where the time is spent. One option is to use a profiler, either the one built into Visual Studio or a third-party profiler like Redgate's Ants Profiler or the Yourkit .Net Profiler.
Another is to trace the time taken using the System.Diagnostics.Stopwatch class and use the results to guide your optimization efforts. For example time the function that retrieves data from Active Directory and separately time the function that populates the view to narrow down where the bottleneck is.
If the bottleneck is in the Active Directory lookup you may want to consider running the operation asynchronously so that the window is not blocked and populates as new data is retrieved. If it's in the listview you may want to consider for example inserting the data in a batch operation.

How to sync for the emails which are received after a particular email.

I am working on an application which download Yahoo account emails in the order of down to top using Yahoo Mail API's.
Application sync logic works like below
Lets say Inbox consists of 1000 emails.
1) Initially fetching 100 emails message ID's by using "ListMessages" with parameters startMid = 0 and numMid=100.
2) Processing chunk emails .
3) Now requesting for the next chunk emails by giving the startMid = 100 and numMid=100.
The above logic works fine if user is not deleting any emails during syncing.
Is there any way to retrieve next chunk emails based on the message ID (string unique value) rather than message number.
What is the logic for syncing the emails from the last processed message?
PS:I can not rely on message number (since message number is not meant for unique identifier of a message).
I was looking for the same thing and found "How to get only emails which are arrived from the Client last sync." (http://developer.yahoo.com/forum/Yahoo-Mail-Web-Services-API/How-to-get-only-emails-which/1320329478746-16f18e6a-aadd-40c3-b259-e095ce80a1e6) where some guy reply "This feature is not available right now but we do plan to support this in future." date: 3 Nov 2011 11:24 AM
I think you can query mailTables (with YQL) or ListMessage (Api) and get the complete list of messages id (without any info) eg: SELECT * FROM ymail.messages WHERE numInfo="0"
And then "count" the position of the last message you got and then, get mail from that number. Eg: SELECT * FROM ymail.messages WHERE startMid="3" and numMid="100"
What do you think?
Greetings from Argentina
PS: sorry about my horrible english