Mùa Covid em đang muốn thể hiện bản đồ các tỉnh thành của Việt Nam có số ca nhiễm là bao nhiêu khi đưa con trỏ chuột vào và tô màu mỗi tỉnh dựa trên tỷ lệ ca nhiễm
Có anh chị em cô chú bác nào đã có file ý tưởng giống như vậy hoặc có bản đồ từng tỉnh thành (ghép lại thành bản đồ Việt Nam) thì cho em xin ạ
Bạn tải File về rồi thực hiện như sau:
1/ Mở File Excel và Click vào A1, trên Ribbon vào Insert > 3D Map (xem hình 1).
2/ Khi Click chọn 3D Map thì xuất hiện như hình 2.
3/ Click vào Open để mở to bản đồ Map Việt Nam như hình 3.
4/ Muốn thể hiện bản đồ riêng cho từng huyện để hiện thị xã thì bạn phải thêm danh sách xã vào, sau đó tạo PivotTable rồi sử dụng Slicer mới xem được.
Bạn nhìn bên phải hình 3 muốn Add layer cáigì đó thì tự tìm hiểu để Add những thứ cần khi rê vào nó sẽ xuất hiện nội dung trên bản đồ khi bạn muốn xem.
Hình như có 'vấn đề'. Các bản đồ đều không thấy quần đảo Hoàng Sa, Trường Sa.
Xem trên Google Maps vẫn thấy các quần đảo.
Thời điểm này khá 'nhạy cảm' nên chắc cần chú thích hay kiểm duyệt gì đó.
Svg là định dạng đồ hoạ 2D vector có thể co dãn mà không bị giảm chất lượng, bị vỡ như hình ảnh ở dạng points. Các đối tượng trên Web được dựng bởi svg rất nhẹ, mượt, mịn màng.
Đồ hoạ 2D thì các đối tượng xác định bởi toạ độ X,Y.
Có phần mềm chuyên thiết kế cái này, còn với files svg đã có thì cách đơn giản nhất là mở nó bằng trình duyệt web rồi view source là thấy luôn và ngay.
Tập tin SVG chẳng qua là tập tin text. Chẳng hạn tập tin tải về là vietnamHigh.svg khi mở bằng notepad như hình ở dưới. Ta thấy là các điểm đường biên của vd. Lai Châu bắt đầu từ <path id="VN-01" title="Lai Châu" ... và kết thúc bằng />.
Từ d="M62.06,32.98 ... cho tới hết là mô tả toàn bộ "đường đi" - path.
path
Cho phép tạo ra nhiều loại đường cong, đường đa giác và hình dạng. Thuộc tính d được sử dụng để mô tả lộ trình của đường cong. Mô tả được thực hiện với các lệnh sau: M (dịch chuyển tới điểm tham chiếu), L (đoạn thẳng), H (đoạn ngang), V (đoạn thẳng đứng), Z (đóng - khép kín đường cong, tức nối với điểm đầu tiên), C (đường cong Beizer), đi kèm theo các tham số .
vd.
<path d = "M1,5L3,2L6,4L7,7Z" />
Tức: nhẩy tới điểm (1; 5) -> đi tới điểm (3; 2) -> đi tới (6; 4) -> đi tới (7; 7) -> đi tới điểm đầu tiên.
vd.
<path d = "M1,5L3,2H5V1 ...
Tức: nhẩy tới điểm (1; 5) -> đi tới điểm (3; 2) -> đi ngang tới x = 5 (đi ngang thì y không đổi, y = 2) -> đi dọc tới y = 1 (đi dọc nên x không đổi, x = 5). Điểm hiện hành là (5; 1)
Đoạn đầu của Lai Châu:
<path d="M62.06,32.98L1.76,0.42L1.04,1 ...
Không biết là khen hay là chê
Ngay từ đầu anh nói là autoshape, tôi nghĩ ngay đến toạ độ từng đỉnh của 1 đa giác.
Nếu nói là toạ độ (kinh độ, vĩ độ) thì không vẽ shape được vì đó là toạ độ góc (angle) tính từ tâm trái đất, không phải giá trị number
Nếu quy ra giá trị number giá trị thực thì không vẽ trên excel được vì quá lớn, phải thu nhỏ (scale) về đơn vị pixel.
Em đã thực hiện được việc tô màu tự động dự trên số ca nhiễm Covid rồi nhưng phần hiển thị tên tỉnh và số liệu ca nhiễm khi nhấp vào từng tỉnh (hoặc rê con trỏ chuột tới) thì chưa làm được. Nó tương tự hoặc gần giống như khi xem bản đồ Covid Việt nam trong đường dẫn bên dưới. Nhờ GPE giúp em giải quyết vấn đề này ạ. Em cảm ơn nhiều!
VnExpress tin tức mới nhất - Thông tin nhanh & chính xác được cập nhật hàng giờ. Đọc báo tin tức online Việt Nam & Thế giới nóng nhất trong ngày về thể thao, thời sự, pháp luật, kinh doanh,...
Cái vụ bản đồ này liên quan tới chính trị.
Nếu chỉ là file cá nhân dùng không sao, còn đăng lên đây là có vấn đề.
Bản đồ trên trang vnexpress vẫn chuẩn có hai quần đảo đó.
BQT nên xem xét sớm vấn đề này, tránh rắc rối (nhắc lần 2).
Cái vụ bản đồ này liên quan tới chính trị.
Nếu chỉ là file cá nhân dùng không sao, còn đăng lên đây là có vấn đề.
Bản đồ trên trang vnexpress vẫn chuẩn có hai quần đảo đó.
BQT nên xem xét sớm vấn đề này, tránh rắc rối (nhắc lần 2).
Em đã thực hiện được việc tô màu tự động dự trên số ca nhiễm Covid rồi nhưng phần hiển thị tên tỉnh và số liệu ca nhiễm khi nhấp vào từng tỉnh (hoặc rê con trỏ chuột tới) thì chưa làm được. Nó tương tự hoặc gần giống như khi xem bản đồ Covid Việt nam trong đường dẫn bên dưới. Nhờ GPE giúp em giải quyết vấn đề này ạ. Em cảm ơn nhiều!
VnExpress tin tức mới nhất - Thông tin nhanh & chính xác được cập nhật hàng giờ. Đọc báo tin tức online Việt Nam & Thế giới nóng nhất trong ngày về thể thao, thời sự, pháp luật, kinh doanh,...
Do không phải là biểu đồ (chart) nên không tự động hiển thị. Dùng VBA thì autoshape không có trong sự kiện worksheet selection change, bản thân nó không có sự kiện để bắt.
Vụ bản đồ này gần đây được đặc biệt quan tâm.
Nếu nói như anh thì những vụ cài cắm bản đồ đã xử lý đều không bắt lỗi được sao ạ?
Cái này là rơi vào lỗi biết mà không khai báo, biết mà cố tình dùng, có thể thêm lỗi quảng bá trên mạng. Nếu sử dụng ở phạm vi ngoài nước thì đúng là chịu, còn đây đang trong nước mà anh.
Mà thôi, tùy các anh.
Vụ bản đồ này gần đây được đặc biệt quan tâm.
Nếu nói như anh thì những vụ cài cắm bản đồ đã xử lý đều không bắt lỗi được sao ạ?
Cái này là rơi vào lỗi biết mà không khai báo, biết mà cố tình dùng, có thể thêm lỗi quảng bá trên mạng. Nếu sử dụng ở phạm vi ngoài nước thì đúng là chịu, còn đây đang trong nước mà anh.
Mà thôi, tùy các anh.
Hai bài trên tôi chỉ mới nói với tư cách cá nhân, để tôi lấy ý kiến ban quản trị rồi xử lý.
Quan điểm tiêng của tôi là "không cố ý". Tôi xài excel và không biết các công cụ vẽ khác, và excel lấy từ Bing nó như thế.
Ví dụ in băng rôn, biểu ngữ, vẽ logo, in tờ rơi, sơn bảng số xe, ... mà không có đầy đủ thì mới là lỗi cố ý.
Hai bài trên tôi chỉ mới nói với tư cách cá nhân, để tôi lấy ý kiến ban quản trị rồi xử lý.
Quan điểm tiêng của tôi là "không cố ý". Tôi xài excel và không biết các công cụ vẽ khác, và excel lấy từ Bing nó như thế.
Ví dụ in băng rôn, biểu ngữ, vẽ logo, in tờ rơi, sơn bảng số xe, ... mà không có đầy đủ thì mới là lỗi cố ý.
Bản đồ nước Việt Nam không có 2 quần đảo Hoàng Sa và Trường Sa của Việt Nam, xét về "tình" không thể chấp nhận xét về lý thì vi phạm pháp luật
Diễn đàn có tầm ảnh hưởng khá lớn với đông đảo thành viên, bên an ninh chắc chắn theo dõi các bài đăng, dính tới lỗi bản đồ Việt Nam vì bất cứ lý do nào cũng rất dể bị mời uống trà
Em đã thực hiện được việc tô màu tự động dự trên số ca nhiễm Covid rồi nhưng phần hiển thị tên tỉnh và số liệu ca nhiễm khi nhấp vào từng tỉnh (hoặc rê con trỏ chuột tới) thì chưa làm được.
Chỉ là ý kiến cá nhân thôi. Tôi không rõ trong hàng ngàn sách báo, bản đồ trên mạng, dùng trong từng cơ quan, tóm lại trong tất cả các bản đồ đang ở đâu đó trong sách báo, giường tủ, trong đất nước Việt Nam, liệu trong tất cả các bản đồ đó đều có Hoàng Sa và Trường Sa. Và sẽ ra sao nếu ngoài Hoàng Sa và Trường Sa ra, nếu bản đồ thiếu một hòn đảo nhỏ tí nào đó (Quảng Ninh?) thì có là vi phạm pháp luật hay không?
Tôi thì cho rằng:
1. Nếu dùng cho cá nhân, trong phạm vi nhỏ, không thuộc loại giáo dục quảng bá rộng rãi (sách giáo khoa?), không để làm chuẩn, nếu có thiếu Hoàng Sa hay Trường Sa thì cùng lắm là THIẾU SÓT.
2. Nếu dùng, hoặc đặc biệt là quảng bá, bản đồ Trung Cộng mà lại có Hoàng Sa hay Trường Sa thì đó là vi phạm pháp luật, là chính trị.
1. là chuyện thiếu sót, nói cho cùng tôi không gán Trường Sa cho Trung Cộng hay bất cứ Lào, Nga ... Còn 2. thì rõ ràng là tôi đã cho là Trường Sa là của Trung Cộng. Hai sự việc là khác nhau, tầm quan trọng là khác nhau.
Cảm ơn Bác thật nhiều! Bác giỏi quá. Cháu thấy nó chạy được, có điều ở lần mở khác thấy có báo lỗi ở dòng: Application.OnTime lastTime, "doi_mau" ạ. Sau đó tắt đi mở lại thì lại bình thường.
Cảm ơn nhiều người đã quan tâm và nhắc nhở sự nhạy cảm của vấn đề này.
Hiện giờ Bình là người có thể bị gọi tên trong vai trò quản lý diễn đàn. Và Bình không muốn mạo hiểm (hoặc tốn thời gian) cho chuyện này.
Mọi người thông cảm nhé. Trong vòng 1 tiếng đồng hồ, những bản đồ không có TS, HS sẽ bị gở xuống.
Thân
Bình
@hoangminhtien bài của anh đầu tiên trong danh sách bị xem xét. thân.
Cảm ơn nhiều người đã quan tâm và nhắc nhở sự nhạy cảm của vấn đề này.
Hiện giờ Bình là người có thể bị gọi tên trong vai trò quản lý diễn đàn. Và Bình không muốn mạo hiểm (hoặc tốn thời gian) cho chuyện này.
Mọi người thông cảm nhé. Trong vòng 1 tiếng đồng hồ, những bản đồ không có TS, HS sẽ bị gở xuống.
Thân
Bình
@hoangminhtien bài của anh đầu tiên trong danh sách bị xem xét. thân.
Nói ra thì cũng là câu chuyện để suy ngẫm. Office 2016 phát hành từ mấy năm rồi, sử dụng rất phổ biến tại Việt Nam, trong đó sử dụng map chart để vẽ biểu đồ Việt Nam mà ko có HS, TS chả thấy ai nói gì... Người ta sử dụng nguồn đó để đăng bài thì bị gắn nhãn?
Cảm ơn nhiều người đã quan tâm và nhắc nhở sự nhạy cảm của vấn đề này.
Hiện giờ Bình là người có thể bị gọi tên trong vai trò quản lý diễn đàn. Và Bình không muốn mạo hiểm (hoặc tốn thời gian) cho chuyện này.
Mọi người thông cảm nhé. Trong vòng 1 tiếng đồng hồ, những bản đồ không có TS, HS sẽ bị gở xuống.
Thân
Bình
@hoangminhtien bài của anh đầu tiên trong danh sách bị xem xét. thân.
Những bài nào mà có thể chưa phù hợp, gây rủi do cho diễn đàn thì anh gỡ đi anh ạ.
Tuy nhiên, chúng ta cũng cần phản hồi lại với Microsoft bổ xung Hoàng Sa và Trường Sa với mục map chart này, chứ không diễn đàn ta mãi mãi không được sử dụng nó.
Vậy là từ xưa tới nay, đơn vị chủ quản là Bộ Thông tin truyền thông mới phản ánh với google map về HS, TS. Không hiểu họ có nắm được thông tin là Microsoft (Bing map) cũng ko có TS, HS
Vậy là từ xưa tới nay, đơn vị chủ quản là Bộ Thông tin truyền thông mới phản ánh với google map về HS, TS. Không hiểu họ có nắm được thông tin là Microsoft (Bing map) cũng ko có TS, HS
Nói chung ta nói ta đúng, họ nói họ đúng - Thế giới thì không có luật chung cho tất cả (nếu có chung cũng chỉ là 1 nhóm nước nào ký với nhau, nói khác đi là rất lỏng lẻo thiếu chế tài, pháp tài)
Dùng hay không là do ta quyết định, nên chọn sản phẩm tốt mà dùng
Để nhiều người khỏi hiểu lầm thì tôi nói rõ. Không phải là tập tin chỉ làm cho 64 bit. Tập tin làm để chạy trên cả 32 bit và 64 bit. 32 bit thì tôi có nên đã kiểm tra rồi. Chỉ không có 64 bit nên muốn nhờ kiểm tra trên 64 bit.
Để nhiều người khỏi hiểu lầm thì tôi nói rõ. Không phải là tập tin chỉ làm cho 64 bit. Tập tin làm để chạy trên cả 32 bit và 64 bit. 32 bit thì tôi có nên đã kiểm tra rồi. Chỉ không có 64 bit nên muốn nhờ kiểm tra trên 64 bit.
cháu ghi lại màn hình chú xem nhé, nhanh quá cháu kịp bấm vào được cái gì cả,hình như là khi đặt chuột ở các ô trên bảng tính thì mới bị, đúng rồi bật lên để không thì không sao nếu di chuyển trên bảng tính là bị lỗi vậy.
cháu ghi lại màn hình chú xem nhé, nhanh quá cháu kịp bấm vào được cái gì cả,hình như là khi đặt chuột ở các ô trên bảng tính thì mới bị, đúng rồi bật lên để không thì không sao nếu di chuyển trên bảng tính là bị lỗi vậy.
Để nhiều người khỏi hiểu lầm thì tôi nói rõ. Không phải là tập tin chỉ làm cho 64 bit. Tập tin làm để chạy trên cả 32 bit và 64 bit. 32 bit thì tôi có nên đã kiểm tra rồi. Chỉ không có 64 bit nên muốn nhờ kiểm tra trên 64 bit.
#If VBA7 Then
Private Sub SetStyleBit(style As LongPtr, ByVal bit As Long, ByVal bSet As Boolean)
#Else
Private Sub SetStyleBit(style As Long, ByVal bit As Long, ByVal bSet As Boolean)
#End If
#If VBA7 Then
Private Sub SetStyleBit(style As LongPtr, ByVal bit As Long, ByVal bSet As Boolean)
#Else
Private Sub SetStyleBit(style As Long, ByVal bit As Long, ByVal bSet As Boolean)
#End If
Đã sửa như bài #53 và chạy êm ru.
Em sửa cái hàm SetStyleBit như kiểu trên vì LongPtr vẫn nhận dạng được trong Office 32bit + Windows 64bit (còn trong Windows 32bit + Office 32bit thì không có tạo máy ảo đế test).
#If VBA7 Then
Private Sub SetStyleBit(style As LongPtr, ByVal bit As Long, ByVal bSet As Boolean)
#Else
Private Sub SetStyleBit(style As Long, ByVal bit As Long, ByVal bSet As Boolean)
#End If
Private Sub SetStyleBit(style As Long, ByVal bit As Long, ByVal bSet As Boolean)
Sửa thành
Mã:
#If VBA7 Then
Private Sub SetStyleBit(style As LongPtr, ByVal bit As Long, ByVal bSet As Boolean)
#Else
Private Sub SetStyleBit(style As Long, ByVal bit As Long, ByVal bSet As Boolean)
#End If
Tóm lại ngoài khai báo style có thiếu sót thì khi CLICK trên sheet có lỗi là do có "xung đột".
Giải thích thêm cho những người thích Windows API hiểu.
1. Tại sao trong tập tin dùng OnTime không có lỗi khi CLICK trên sheet? OnTime dùng để chạy sub doi_mau. OnTime của VBA nên do Excel chạy, cứ sau 1 s thì Excel sẽ gọi doi_moi. Khi Excel bận thì dù 1 s đã qua thì nó cũng không gọi doi_moi mà làm xong các việc bận mới gọi doi_moi. Excel tự gọi nên nó làm chủ được tình huống. Không có xung đột gì ở đây.
2. Tại sao dùng SetTimer của Windows API thì lỗi khi CLICK trên sheet?
Ta phân tích dòng code
Mã:
ID = SetTimer(0, 0, 200, AddressOf TimerProc)
Dòng code trên có nghĩa là ta đã gọi hàm SetTimer của system Windows, kiểu như: báo cáo sếp (Windows), tôi đặt nhiệm vụ là cứ 200 ms thì thực hiện code của tôi, tức TimerProc, ở địa chỉ xyz trong bộ nhớ. Lúc đó system Windows sẽ tạo 1 "đồng hồ", cứ 200 ms sẽ gọi sub TimerProc. Tất nhiên 200 ms là thời gian mặc định. Khi 200 ms trôi qua mà đúng lúc system bận (ngoài process của ta còn vô vàn process khác trong system, bản thân system có những lúc bận) thì system sẽ gọi TimerProc vào lúc sau. Nhưng đây là nói về việc system bận, còn chuyện Excel lúc đó có bận hay không thì system không quan tâm, cứ 200 ms là gọi TimerProc. Hàm SetTimer trả về một giá trị được ghi nhớ trong biến ID. Khi cần "hủy" đồng hồ thì gọi KillTimer và truyền ID vào để hủy đồng hồ. Tại sao KillTimer không đủ để hủy đồng hồ mà lại phải truyền ID vào? Đơn giản là mỗi app có thể tạo nhiều đồng hồ do có nhu cầu. Khi muốn hủy 1 đồng hồ nào đấy mà chỉ cần gọi KillTimer không có tham số thì cụ thánh của system Windpows cũng chịu không biết "người ta" cần hủy đồng hồ nào. Vì thế mỗi đồng hồ được tạo bởi SetTimer sẽ được gán cho một con số định danh, và SetTimer khi tạo đồng hồ sẽ trả về con số định danh (ID) đó của đồng hồ được tạo. Khi cần hủy đồng hồ nào thì gọi KillTimer và truyền con số định danh (ID) của nó vào.
Khi chạy chương trình thì code và dữ liệu (data) sẽ được load vào bộ nhớ. Mọi chuyện sảy ra là sảy ra trong bộ nhớ. Sub TimerProc nằm đâu đó trong bộ nhớ. Trong trường hợp này TimerProc được gọi bởi system Windows chứ không bởi Excel. Vì mình có "khai báo" gì với Excel đâu mà nó biết khi nào phải gọi cái gọi là TimerProc. Để Windows có thể gọi TimerProc thì phải cung cấp cho Windows địa chỉ của TimerProc trong bộ nhớ. Windows biết TimerProc ở đâu thì cứ "đến giở" là gọi nó thôi. Ta cung cấp cho Windows địa chỉ trong RAM của TimerProc bằng hàm: AddressOf TimerProc sẽ trả về địa chỉ của TimerProc trong RAM. Khi đến giờ là Windows gọi TimerProc để thực thi. Nếu đúng lúc đó người dùng CLICK trên sheet thì code của Excerl cũng được thực thi (nếu vd. Excel phát hiện có Worksheet_SelectionChange thì code của Worksheet_SelectionChange sẽ được thực thi). 2 vị khác nhau cùng thực hiện việc của mình thì sảy ra "xung đột".
Hàm mà khi gọi một hàm nào đó của Windows API ta phải cung cấp cho Windows địa chỉ của nó, để Windows biết nó nằm ở đâu trong RAM để sau đó gọi nó, hàm đó được gọi là call back. TimerProc là một call back.
Private Sub SetStyleBit(style As Long, ByVal bit As Long, ByVal bSet As Boolean)
Sửa thành
Mã:
#If VBA7 Then
Private Sub SetStyleBit(style As LongPtr, ByVal bit As Long, ByVal bSet As Boolean)
#Else
Private Sub SetStyleBit(style As Long, ByVal bit As Long, ByVal bSet As Boolean)
#End If
Tóm lại ngoài khai báo style có thiếu sót thì khi CLICK trên sheet có lỗi là do có "xung đột".
Giải thích thêm cho những người thích Windows API hiểu.
1. Tại sao trong tập tin dùng OnTime không có lỗi khi CLICK trên sheet? OnTime dùng để chạy sub doi_mau. OnTime của VBA nên do Excel chạy, cứ sau 1 s thì Excel sẽ gọi doi_moi. Khi Excel bận thì dù 1 s đã qua thì nó cũng không gọi doi_moi mà làm xong các việc bận mới gọi doi_moi. Excel tự gọi nên nó làm chủ được tình huống. Không có xung đột gì ở đây.
2. Tại sao dùng SetTimer của Windows API thì lỗi khi CLICK trên sheet?
Ta phân tích dòng code
Mã:
ID = SetTimer(0, 0, 200, AddressOf TimerProc)
Dòng code trên có nghĩa là ta đã gọi hàm SetTimer của system Windows, kiểu như: báo cáo sếp (Windows), tôi đặt nhiệm vụ là cứ 200 ms thì thực hiện code của tôi, tức TimerProc, ở địa chỉ xyz trong bộ nhớ. Lúc đó system Windows sẽ tạo 1 "đồng hồ", cứ 200 ms sẽ gọi sub TimerProc. Tất nhiên 200 ms là thời gian mặc định. Khi 200 ms trôi qua mà đúng lúc system bận (ngoài process của ta còn vô vàn process khác trong system, bản thân system có những lúc bận) thì system sẽ gọi TimerProc vào lúc sau. Nhưng đây là nói về việc system bận, còn chuyện Excel lúc đó có bận hay không thì system không quan tâm, cứ 200 ms là gọi TimerProc. Hàm SetTimer trả về một giá trị được ghi nhớ trong biến ID. Khi cần "hủy" đồng hồ thì gọi KillTimer và truyền ID vào để hủy đồng hồ. Tại sao KillTimer không đủ để hủy đồng hồ mà lại phải truyền ID vào? Đơn giản là mỗi app có thể tạo nhiều đồng hồ do có nhu cầu. Khi muốn hủy 1 đồng hồ nào đấy mà chỉ cần gọi KillTimer không có tham số thì cụ thánh của system Windpows cũng chịu không biết "người ta" cần hủy đồng hồ nào. Vì thế mỗi đồng hồ được tạo bởi SetTimer sẽ được gán cho một con số định danh, và SetTimer khi tạo đồng hồ sẽ trả về con số định danh (ID) đó của đồng hồ được tạo. Khi cần hủy đồng hồ nào thì gọi KillTimer và truyền con số định danh (ID) của nó vào.
Khi chạy chương trình thì code và dữ liệu (data) sẽ được load vào bộ nhớ. Mọi chuyện sảy ra là sảy ra trong bộ nhớ. Sub TimerProc nằm đâu đó trong bộ nhớ. Trong trường hợp này TimerProc được gọi bởi system Windows chứ không bởi Excel. Vì mình có "khai báo" gì với Excel đâu mà nó biết khi nào phải gọi cái gọi là TimerProc. Để Windows có thể gọi TimerProc thì phải cung cấp cho Windows địa chỉ của TimerProc trong bộ nhớ. Windows biết TimerProc ở đâu thì cứ "đến giở" là gọi nó thôi. Ta cung cấp cho Windows địa chỉ trong RAM của TimerProc bằng hàm: AddressOf TimerProc sẽ trả về địa chỉ của TimerProc trong RAM. Khi đến giờ là Windows gọi TimerProc để thực thi. Nếu đúng lúc đó người dùng CLICK trên sheet thì code của Excerl cũng được thực thi (nếu vd. Excel phát hiện có Worksheet_SelectionChange thì code của Worksheet_SelectionChange sẽ được thực thi). 2 vị khác nhau cùng thực hiện việc của mình thì sảy ra "xung đột".
Hàm mà khi gọi một hàm nào đó của Windows API ta phải cung cấp cho Windows địa chỉ của nó, để Windows biết nó nằm ở đâu trong RAM để sau đó gọi nó, hàm đó được gọi là call back. TimerProc là một call back.
Hay quá code vẫn chạy êm như tiếng hát ru chú ạ.
Chú ơi cháu thấy có một vấn đề khi chỉ vào bản đồ (vùng màu xanh) vùng này có phải là Hà Nội không mà không xuất hiện thông tin tên thành phố chú nhỉ? Khi chỉ đến vùng khác thì hiển thị, hình ảnh là cháu đang chỉ vào Nam Định sau đó di chuyển về vùng xanh thông tin trên cái form hiển thị không thay đổi vẫn hiện Nam Định. Như vậy là có phải là vấn đề hay không chú nhỉ, cháu chưa hiểu cái món này:
Hay quá code vẫn chạy êm như tiếng hát ru chú ạ.
Chú ơi cháu thấy có một vấn đề khi chỉ vào bản đồ (vùng màu xanh) vùng này có phải là Hà Nội không mà không xuất hiện thông tin tên thành phố chú nhỉ? Khi chỉ đến vùng khác thì hiển thị, hình ảnh là cháu đang chỉ vào Nam Định sau đó di chuyển về vùng xanh thông tin trên cái form hiển thị không thay đổi vẫn hiện Nam Định. Như vậy là có phải là vấn đề hay không chú nhỉ, cháu chưa hiểu cái món này:
Báo cáo chú, cháu đã thử sau: mở loa to, di chuyển các ô, nhập liệu tô màu , thao tác, thậm trí tô cả màu bản đồ sang ánh nắng vàng rực rỡ... rồi trỏ di chuyển chuột nó vẫn đổ lại màu xanh
Sau đó update , màu vàng rực rỡ đã mất. Kết luận: kết quả hơn cả mong đợi, code hoạt động êm loa không phát ra tiếng binh bong, màn hình không hiển thị lỗi.
Đã nhìn thấy tên thủ đô "Hà Nội",cảm ơn chú rất nhiều, file này của chú cháu đã lưu vào thư mục yêu thích.
Private Function create_shape(sh As Worksheet, arrPolygon() As Double, ByVal count As Long, ByVal scale_ As Double, ByVal offsetX As Double, ByVal offsetY As Double) As Shape
Dim r As Long
For r = 1 To count
arrPolygon(r, 1) = (arrPolygon(r, 1) + offsetX) * scale_
arrPolygon(r, 2) = (arrPolygon(r, 2) + offsetY) * scale_
Next r
With sh
With .Shapes.BuildFreeform(msoEditingCorner, arrPolygon(1, 1), arrPolygon(1, 2))
For r = 2 To count
.AddNodes msoSegmentLine, msoEditingAuto, arrPolygon(r, 1), arrPolygon(r, 2)
Next r
Set create_shape = .ConvertToShape
End With
End With
End Function
5. Tôi không vẽ lại Hà Nội. Trên bản đồ của chủ thớt đã có 2 vùng. Tôi chỉ sửa thôi.
Click vùng xanh ở bài 61 thì nhìn Name Box bạn sẽ thấy Hà Nội. Nhưng click lần nữa thì ở Name Box lại là b. Click tương tự vùng đỏ giáp với vùng xanh thì có Hà Nội, nhưng click lần nữa thì lại là a. a và b được gộp (Group) thành shape "lớn" có tên là Hà Nội. Nếu click 1 lần vào các đảo của Quảng Ninh thì ở Name Box luôn có Quảng Ninh. Nhưng click lần 2 thì là Freeform ...
Vấn đề ở chỗ với code
Mã:
Set obj = ActiveWindow.RangeFromPoint(pt.x, pt.y)
thì obj.Name lại không là Quảng Ninh mà là Freeform ..., còn với Hà Nội thì obj.Name là a hoặc b. Vì lý do này mà tôi phải mất công từ Freeform ... (Quảng Ninh và các tỉnh có nhiều vùng tương tự) suy ra tên tỉnh là Quảng Ninh bằng code
Mã:
shapeName = obj.Name ' (A)
If InStr(1, obj.Name, "Freeform", vbTextCompare) = 1 Then
For Each shp In Sheet4.Shapes
If shp.Type = msoGroup Then
For Each item In shp.GroupItems
If item.Name = shapeName Then
shapeName = shp.Name ' (B)
timthay = True
Exit For
End If
Next item
If timthay Then Exit For
End If
Next shp
End If
Tức nếu obj.Name không có đoạn đầu là "Freeform" thì đó cũng chính là tên nhóm (Group) - tên tỉnh (ở dòng (A)). Trong trường hợp ngược lại thì tên tỉnh được sửa lại ở dòng (B). Hiểu được đoạn code này thì sửa dễ dàng.
Ai muốn tự làm để kiểm nghiệm, thỏa trí tò mò thì làm như sau: click 2 lần (2 lần chứ không phải là đúp) vào Hà Nội cũ -> trong Name Box có a -> sửa thành vd. Freeform 999. Click 2 lần vào Hà Tây cũ -> trong Name Box có b -> sửa thành vd. Freeform 1000. Bây giờ obj.Name sẽ là Freeform 999 hoặc Freeform 1000 và tên tỉnh sẽ được trả về ở dòng (B).
@batman1 :
Tôi biết rồi:
Do tôi ghi macro, thấy nó cho msoSegmentCurve thì tôi dùng nó. Nhưng nay thấy code của bác tôi thay msoSegmentCurve bằng msoSegmentLine là vẽ nhanh liền.
P/S: Bác cho tôi xin dãy tọa độ của Hà Nội gộp với Hà Tây với bác!
@batman1 :
Tôi biết rồi:
Do tôi ghi macro, thấy nó cho msoSegmentCurve thì tôi dùng nó. Nhưng nay thấy code của bác tôi thay msoSegmentCurve bằng msoSegmentLine là vẽ nhanh liền.
P/S: Bác cho tôi xin dãy tọa độ của Hà Nội gộp với Hà Tây với bác!
Chú xem có thể kết hợp thêm chức năng vẽ lại bản đồ được không ạ, khi chiều cháu test co kéo rồi xóa bản đồ, xong phải tải lại file của chú,nếu có nút cập nhật lại ảnh bản đồ nữa thì hoàn hảo quá.
Ồ thì ra vậy, cái bản đồ là tự dùng chỉ số tọa độ để vẽ,bái phục các bác.
Nếu vẽ được như vậy thì bài này của chú BATMAN:
Chú xem có thể kết hợp thêm chức năng vẽ lại bản đồ được không ạ, khi chiều cháu test co kéo rồi xóa bản đồ, xong phải tải lại file của chú,nếu có nút cập nhật lại ảnh bản đồ nữa thì hoàn hảo quá.
Nếu muốn vẽ bản đồ to nhỏ thì sửa scale_. Vd. scale_ = 2 thì bản đồ to gấp đôi. Nếu offsetX và offsetY tăng thì bản đồ sẽ dịch xuống dưới và dịch sang phải.
Trong tập tin dữ liệu cho Hà Nội đã được gộp từ Hà Nội cũ và Hà Tây cũ.
Code cũng đơn giản thôi. Toàn bộ code trong Module1
Mã:
Option Explicit
Sub create_map()
Const scale_ = 1
Const offsetX = 10
Const offsetY = 10
Dim firstRow As Long, lastRow As Long, chiso1 As Long, chiso2 As Long, curr_col As Long, k As Long, n As Long
Dim shp_name() As String, ten As String, Points(), shp As Shape
ten = Sheet1.Range("A2").Value
For k = 1 To 63
If Sheet4.Cells(1, 2 * k - 1).Value = ten Then Exit For
Next k
If k > 63 Then
Sheet1.Range("A2").Value = Empty ' khong tim thay ten tinh nen xoa ten tinh
chiso1 = 1
chiso2 = 63
Else
chiso1 = k
chiso2 = k
End If
For k = chiso1 To chiso2
n = 0
curr_col = 2 * k - 1
firstRow = Rows.count
Do While firstRow > 2
lastRow = firstRow - 1
lastRow = Sheet4.Cells(lastRow, curr_col + 1).End(xlUp).Row
firstRow = Sheet4.Cells(lastRow, curr_col + 1).End(xlUp).Row
n = n + 1
ReDim Preserve shp_name(1 To n)
Points = Sheet4.Range(Sheet4.Cells(firstRow, curr_col), Sheet4.Cells(lastRow, curr_col + 1)).Value
shp_name(n) = create_shape(Sheet1, Points, UBound(Points, 1), scale_, offsetX, offsetY).Name
Loop
If UBound(shp_name) = 1 Then
Set shp = Sheet1.Shapes(shp_name(1))
Else
Set shp = Sheet1.Shapes.Range(shp_name).Group
End If
With shp
.Name = Sheet4.Cells(1, curr_col).Value
.Fill.ForeColor.RGB = RGB(141, 180, 226)
.Line.Weight = 0.25
.Line.ForeColor.RGB = RGB(255, 255, 255)
.Placement = xlMove
End With
Next k
End Sub
Private Function create_shape(sh As Worksheet, arrPolygon(), ByVal count As Long, ByVal scale_ As Double, ByVal offsetX As Double, ByVal offsetY As Double) As Shape
Dim r As Long
For r = 1 To count
arrPolygon(r, 1) = (arrPolygon(r, 1) + offsetX) * scale_
arrPolygon(r, 2) = (arrPolygon(r, 2) + offsetY) * scale_
Next r
With sh
With .Shapes.BuildFreeform(msoEditingCorner, arrPolygon(1, 1), arrPolygon(1, 2))
For r = 2 To count
.AddNodes msoSegmentLine, msoEditingAuto, arrPolygon(r, 1), arrPolygon(r, 2)
Next r
Set create_shape = .ConvertToShape
End With
End With
End Function
Nếu muốn vẽ bản đồ to nhỏ thì sửa scale_. Vd. scale_ = 2 thì bản đồ to gấp đôi. Nếu offsetX và offsetY tăng thì bản đồ sẽ dịch xuống dưới và dịch sang phải.
Trong tập tin dữ liệu cho Hà Nội đã được gộp từ Hà Nội cũ và Hà Tây cũ.
Code cũng đơn giản thôi. Toàn bộ code trong Module1
Mã:
Option Explicit
Sub create_map()
Const scale_ = 1
Const offsetX = 10
Const offsetY = 10
Dim firstRow As Long, lastRow As Long, chiso1 As Long, chiso2 As Long, curr_col As Long, k As Long, n As Long
Dim shp_name() As String, ten As String, Points(), shp As Shape
ten = Sheet1.Range("A2").Value
For k = 1 To 63
If Sheet4.Cells(1, 2 * k - 1).Value = ten Then Exit For
Next k
If k > 63 Then
Sheet1.Range("A2").Value = Empty ' khong tim thay ten tinh nen xoa ten tinh
chiso1 = 1
chiso2 = 63
Else
chiso1 = k
chiso2 = k
End If
For k = chiso1 To chiso2
n = 0
curr_col = 2 * k - 1
firstRow = Rows.count
Do While firstRow > 2
lastRow = firstRow - 1
lastRow = Sheet4.Cells(lastRow, curr_col + 1).End(xlUp).Row
firstRow = Sheet4.Cells(lastRow, curr_col + 1).End(xlUp).Row
n = n + 1
ReDim Preserve shp_name(1 To n)
Points = Sheet4.Range(Sheet4.Cells(firstRow, curr_col), Sheet4.Cells(lastRow, curr_col + 1)).Value
shp_name(n) = create_shape(Sheet1, Points, UBound(Points, 1), scale_, offsetX, offsetY).Name
Loop
If UBound(shp_name) = 1 Then
Set shp = Sheet1.Shapes(shp_name(1))
Else
Set shp = Sheet1.Shapes.Range(shp_name).Group
End If
With shp
.Name = Sheet4.Cells(1, curr_col).Value
.Fill.ForeColor.RGB = RGB(141, 180, 226)
.Line.Weight = 0.25
.Line.ForeColor.RGB = RGB(255, 255, 255)
.Placement = xlMove
End With
Next k
End Sub
Private Function create_shape(sh As Worksheet, arrPolygon(), ByVal count As Long, ByVal scale_ As Double, ByVal offsetX As Double, ByVal offsetY As Double) As Shape
Dim r As Long
For r = 1 To count
arrPolygon(r, 1) = (arrPolygon(r, 1) + offsetX) * scale_
arrPolygon(r, 2) = (arrPolygon(r, 2) + offsetY) * scale_
Next r
With sh
With .Shapes.BuildFreeform(msoEditingCorner, arrPolygon(1, 1), arrPolygon(1, 2))
For r = 2 To count
.AddNodes msoSegmentLine, msoEditingAuto, arrPolygon(r, 1), arrPolygon(r, 2)
Next r
Set create_shape = .ConvertToShape
End With
End With
End Function